build: add freebsd support (#4049)
This commit is contained in:
parent
2dbe837ebc
commit
1d6d916b7a
31 changed files with 1055 additions and 39 deletions
272
.github/workflows/ci-freebsd.yml
vendored
Normal file
272
.github/workflows/ci-freebsd.yml
vendored
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
---
|
||||||
|
name: CI-FreeBSD
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
release_commit:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
release_version:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
BRANCH: ${{ github.head_ref || github.ref_name }}
|
||||||
|
BUILD_VERSION: ${{ inputs.release_version }}
|
||||||
|
COMMIT: ${{ inputs.release_commit }}
|
||||||
|
FREEBSD_CLANG_VERSION: 19
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
setup-matrix:
|
||||||
|
name: Setup Build Matrix
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.generate-matrix.outputs.matrix }}
|
||||||
|
steps:
|
||||||
|
- name: Generate Matrix
|
||||||
|
id: generate-matrix
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# Base matrix with amd64 build
|
||||||
|
matrix='{
|
||||||
|
"include": [
|
||||||
|
{
|
||||||
|
"bsd_release": "14.3",
|
||||||
|
"arch": "x86_64",
|
||||||
|
"cmake_processor": "amd64",
|
||||||
|
"runner": "ubuntu-latest"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
|
||||||
|
# Add aarch64 build only if not a pull request event
|
||||||
|
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
|
||||||
|
matrix=$(echo "$matrix" | jq '.include += [{
|
||||||
|
"bsd_release": "14.3",
|
||||||
|
"arch": "aarch64",
|
||||||
|
"cmake_processor": "aarch64",
|
||||||
|
"runner": "ubuntu-latest"
|
||||||
|
}]')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use heredoc for multiline JSON output
|
||||||
|
{
|
||||||
|
echo "matrix<<EOF"
|
||||||
|
echo "$matrix"
|
||||||
|
echo "EOF"
|
||||||
|
} >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
echo "Generated matrix:"
|
||||||
|
echo "$matrix" | jq .
|
||||||
|
|
||||||
|
build_freebsd:
|
||||||
|
name: ${{ matrix.cmake_processor }}-${{ matrix.bsd_release }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: setup-matrix
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Get Processor Count
|
||||||
|
id: processor_count
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
PROCESSOR_COUNT=$(nproc)
|
||||||
|
echo "PROCESSOR_COUNT=${PROCESSOR_COUNT}" >> "${GITHUB_OUTPUT}"
|
||||||
|
echo "PROCESSOR_COUNT: $PROCESSOR_COUNT"
|
||||||
|
|
||||||
|
- name: Setup FreeBSD
|
||||||
|
uses: vmactions/freebsd-vm@783ae15c0393f8a2582a139f76cc55f2d887b4a6 # v1.2.6
|
||||||
|
with:
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
cpu: ${{ steps.processor_count.outputs.PROCESSOR_COUNT }}
|
||||||
|
envs: 'BRANCH BUILD_VERSION COMMIT'
|
||||||
|
# TODO: there is no libcap for freebsd... we need graphics/libdrm if we find a way to use libcap
|
||||||
|
# TODO: docs are off because doxygen is too old: https://www.freshports.org/devel/doxygen/ must be >= 1.10
|
||||||
|
prepare: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
pkg update
|
||||||
|
pkg upgrade -y
|
||||||
|
pkg install -y \
|
||||||
|
audio/opus \
|
||||||
|
audio/pulseaudio \
|
||||||
|
devel/boost-all \
|
||||||
|
devel/cmake-core \
|
||||||
|
devel/evdev-proto \
|
||||||
|
devel/git \
|
||||||
|
devel/libayatana-appindicator \
|
||||||
|
devel/libevdev \
|
||||||
|
devel/libnotify \
|
||||||
|
devel/llvm${{ env.FREEBSD_CLANG_VERSION }} \
|
||||||
|
devel/ninja \
|
||||||
|
devel/pkgconf \
|
||||||
|
ftp/curl \
|
||||||
|
graphics/libdrm \
|
||||||
|
graphics/wayland \
|
||||||
|
lang/python312 \
|
||||||
|
multimedia/libva \
|
||||||
|
net/miniupnpc \
|
||||||
|
ports-mgmt/pkg \
|
||||||
|
security/openssl \
|
||||||
|
shells/bash \
|
||||||
|
www/npm \
|
||||||
|
x11/libX11 \
|
||||||
|
x11/libxcb \
|
||||||
|
x11/libXfixes \
|
||||||
|
x11/libXrandr \
|
||||||
|
x11/libXtst \
|
||||||
|
x11-servers/xorg-server
|
||||||
|
|
||||||
|
# create symlink for shebang bash compatibility
|
||||||
|
ln -s /usr/local/bin/bash /bin/bash
|
||||||
|
|
||||||
|
# setup python
|
||||||
|
ln -s /usr/local/bin/python3.12 /usr/local/bin/python
|
||||||
|
python -m ensurepip
|
||||||
|
release: ${{ matrix.bsd_release }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
# install gcvor
|
||||||
|
python -m pip install gcovr
|
||||||
|
|
||||||
|
# fix git safe.directory issues
|
||||||
|
git config --global --add safe.directory "*"
|
||||||
|
sync: nfs # sshfs is used for build-deps; however it's much slower than nfs
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
shell: freebsd {0}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
cd "${GITHUB_WORKSPACE}"
|
||||||
|
|
||||||
|
cc_path="$(which clang${{ env.FREEBSD_CLANG_VERSION }})"
|
||||||
|
cxx_path="$(which clang++${{ env.FREEBSD_CLANG_VERSION }})"
|
||||||
|
|
||||||
|
export CC="${cc_path}"
|
||||||
|
export CXX="${cxx_path}"
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
cmake \
|
||||||
|
-B build \
|
||||||
|
-G Ninja \
|
||||||
|
-S . \
|
||||||
|
-DBUILD_DOCS=OFF \
|
||||||
|
-DBUILD_WERROR=OFF \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr/local \
|
||||||
|
-DSUNSHINE_ASSETS_DIR=share/assets \
|
||||||
|
-DSUNSHINE_EXECUTABLE_PATH=/usr/local/bin/sunshine \
|
||||||
|
-DSUNSHINE_ENABLE_CUDA=OFF \
|
||||||
|
-DSUNSHINE_ENABLE_DRM=OFF \
|
||||||
|
-DSUNSHINE_ENABLE_WAYLAND=ON \
|
||||||
|
-DSUNSHINE_ENABLE_X11=ON \
|
||||||
|
-DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \
|
||||||
|
-DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \
|
||||||
|
-DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support'
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: freebsd {0}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
cd "${GITHUB_WORKSPACE}"
|
||||||
|
ninja -C build
|
||||||
|
|
||||||
|
- name: Package
|
||||||
|
shell: freebsd {0}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
cd "${GITHUB_WORKSPACE}"
|
||||||
|
|
||||||
|
mkdir -p artifacts
|
||||||
|
|
||||||
|
cd build
|
||||||
|
cpack -G FREEBSD
|
||||||
|
|
||||||
|
# move compiled files to artifacts
|
||||||
|
mv ./cpack_artifacts/Sunshine.pkg \
|
||||||
|
../artifacts/Sunshine-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}.pkg
|
||||||
|
|
||||||
|
- name: Debug
|
||||||
|
if: always()
|
||||||
|
shell: bash
|
||||||
|
working-directory: build/cpack_artifacts/_CPack_Packages/FreeBSD/FREEBSD/Sunshine
|
||||||
|
run: |
|
||||||
|
echo "FreeBSD CPack Debug"
|
||||||
|
echo "===== Staging Directory Contents ====="
|
||||||
|
ls -la
|
||||||
|
echo ""
|
||||||
|
echo "===== +MANIFEST Content ====="
|
||||||
|
cat +MANIFEST
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# use tar to print the contents of the pkg
|
||||||
|
cd "${GITHUB_WORKSPACE}/artifacts"
|
||||||
|
echo "===== Package Contents ====="
|
||||||
|
tar -tvf Sunshine-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}.pkg
|
||||||
|
echo ""
|
||||||
|
echo "===== Package Statistics ====="
|
||||||
|
echo -n "Total files in package: "
|
||||||
|
tar -tf Sunshine-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}.pkg 2>&1 | wc -l
|
||||||
|
echo ""
|
||||||
|
echo "Package file size:"
|
||||||
|
ls -lh Sunshine-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}.pkg
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
id: test
|
||||||
|
shell: freebsd {0}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
cd "${GITHUB_WORKSPACE}/build/tests"
|
||||||
|
|
||||||
|
export DISPLAY=:1
|
||||||
|
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
|
||||||
|
XVFB_PID=$!
|
||||||
|
|
||||||
|
./test_sunshine --gtest_color=yes --gtest_output=xml:test_results.xml
|
||||||
|
|
||||||
|
kill ${XVFB_PID}
|
||||||
|
|
||||||
|
- name: Generate gcov report
|
||||||
|
id: test_report
|
||||||
|
# any except canceled or skipped
|
||||||
|
if: >-
|
||||||
|
always() &&
|
||||||
|
(steps.test.outcome == 'success' || steps.test.outcome == 'failure')
|
||||||
|
shell: freebsd {0}
|
||||||
|
run: |
|
||||||
|
cd "${GITHUB_WORKSPACE}/build"
|
||||||
|
python -m gcovr . -r ../src \
|
||||||
|
--exclude-noncode-lines \
|
||||||
|
--exclude-throw-branches \
|
||||||
|
--exclude-unreachable-branches \
|
||||||
|
--verbose \
|
||||||
|
--xml-pretty \
|
||||||
|
-o coverage.xml
|
||||||
|
|
||||||
|
- name: Upload coverage artifact
|
||||||
|
if: >-
|
||||||
|
always() &&
|
||||||
|
(steps.test_report.outcome == 'success')
|
||||||
|
uses: actions/upload-artifact@v5
|
||||||
|
with:
|
||||||
|
name: coverage-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}
|
||||||
|
path: |
|
||||||
|
build/coverage.xml
|
||||||
|
build/tests/test_results.xml
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Upload Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-FreeBSD-${{ matrix.bsd_release }}-${{ matrix.cmake_processor }}
|
||||||
|
path: artifacts/
|
||||||
|
if-no-files-found: error
|
||||||
36
.github/workflows/ci.yml
vendored
36
.github/workflows/ci.yml
vendored
|
|
@ -69,6 +69,14 @@ jobs:
|
||||||
GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
build-freebsd:
|
||||||
|
name: FreeBSD
|
||||||
|
needs: release-setup
|
||||||
|
uses: ./.github/workflows/ci-freebsd.yml
|
||||||
|
with:
|
||||||
|
release_commit: ${{ needs.release-setup.outputs.release_commit }}
|
||||||
|
release_version: ${{ needs.release-setup.outputs.release_version }}
|
||||||
|
|
||||||
build-homebrew:
|
build-homebrew:
|
||||||
name: Homebrew
|
name: Homebrew
|
||||||
needs: release-setup
|
needs: release-setup
|
||||||
|
|
@ -133,6 +141,7 @@ jobs:
|
||||||
!cancelled() &&
|
!cancelled() &&
|
||||||
startsWith(github.repository, 'LizardByte/')
|
startsWith(github.repository, 'LizardByte/')
|
||||||
needs:
|
needs:
|
||||||
|
- build-freebsd
|
||||||
- build-linux
|
- build-linux
|
||||||
- build-linux-flatpak
|
- build-linux-flatpak
|
||||||
- build-homebrew
|
- build-homebrew
|
||||||
|
|
@ -142,29 +151,53 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- name: FreeBSD-14.3-amd64
|
||||||
|
coverage: true
|
||||||
|
pr: true
|
||||||
|
- name: FreeBSD-14.3-aarch64
|
||||||
|
coverage: true
|
||||||
|
pr: false
|
||||||
- name: Linux-AppImage
|
- name: Linux-AppImage
|
||||||
coverage: true
|
coverage: true
|
||||||
|
pr: true
|
||||||
- name: Homebrew-macos-14
|
- name: Homebrew-macos-14
|
||||||
coverage: false
|
coverage: false
|
||||||
|
pr: true
|
||||||
- name: Homebrew-macos-15
|
- name: Homebrew-macos-15
|
||||||
coverage: false
|
coverage: false
|
||||||
|
pr: true
|
||||||
- name: Homebrew-macos-26
|
- name: Homebrew-macos-26
|
||||||
coverage: false
|
coverage: false
|
||||||
|
pr: true
|
||||||
- name: Homebrew-ubuntu-latest
|
- name: Homebrew-ubuntu-latest
|
||||||
coverage: false
|
coverage: false
|
||||||
|
pr: true
|
||||||
- name: Windows-AMD64
|
- name: Windows-AMD64
|
||||||
coverage: true
|
coverage: true
|
||||||
|
pr: true
|
||||||
steps:
|
steps:
|
||||||
|
- name: Should run
|
||||||
|
id: should_run
|
||||||
|
run: |
|
||||||
|
if [ ${{ github.event_name }} != 'pull_request' ] || [ ${{ matrix.pr }} == 'true' ]; then
|
||||||
|
echo "SHOULD_RUN=true" >> "${GITHUB_OUTPUT}"
|
||||||
|
else
|
||||||
|
echo "SHOULD_RUN=false" >> "${GITHUB_OUTPUT}"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
if: steps.should_run.outputs.SHOULD_RUN == 'true'
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Download coverage artifact
|
- name: Download coverage artifact
|
||||||
|
if: steps.should_run.outputs.SHOULD_RUN == 'true'
|
||||||
uses: actions/download-artifact@v6
|
uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
name: coverage-${{ matrix.name }}
|
name: coverage-${{ matrix.name }}
|
||||||
path: _coverage
|
path: _coverage
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
|
if: steps.should_run.outputs.SHOULD_RUN == 'true'
|
||||||
uses: codecov/test-results-action@v1
|
uses: codecov/test-results-action@v1
|
||||||
with:
|
with:
|
||||||
disable_search: true
|
disable_search: true
|
||||||
|
|
@ -175,8 +208,8 @@ jobs:
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
|
if: steps.should_run.outputs.SHOULD_RUN == 'true' && matrix.coverage != false
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@v5
|
||||||
if: matrix.coverage != false
|
|
||||||
with:
|
with:
|
||||||
disable_search: true
|
disable_search: true
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
@ -193,6 +226,7 @@ jobs:
|
||||||
needs:
|
needs:
|
||||||
- release-setup
|
- release-setup
|
||||||
- build-docker
|
- build-docker
|
||||||
|
- build-freebsd
|
||||||
- build-linux
|
- build-linux
|
||||||
- build-linux-flatpak
|
- build-linux-flatpak
|
||||||
- build-homebrew
|
- build-homebrew
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
|
set(FREEBSD ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
# set the module path, used for includes
|
# set the module path, used for includes
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
|
|
||||||
179
README.md
179
README.md
|
|
@ -32,6 +32,166 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
|
||||||
* [Stable Docs](https://docs.lizardbyte.dev/projects/sunshine/latest/)
|
* [Stable Docs](https://docs.lizardbyte.dev/projects/sunshine/latest/)
|
||||||
* [Beta Docs](https://docs.lizardbyte.dev/projects/sunshine/master/)
|
* [Beta Docs](https://docs.lizardbyte.dev/projects/sunshine/master/)
|
||||||
|
|
||||||
|
## 🎮 Feature Compatibility
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<caption id="feature_compatibility">Platform Feature Support</caption>
|
||||||
|
<tr>
|
||||||
|
<th>Feature</th>
|
||||||
|
<th>FreeBSD</th>
|
||||||
|
<th>Linux</th>
|
||||||
|
<th>macOS</th>
|
||||||
|
<th>Windows</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" align="center"><b>Gamepad Emulation</b><br>
|
||||||
|
What type of gamepads can be emulated on the host.<br>
|
||||||
|
Clients may support other gamepads.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DualShock / DS4 (PlayStation 4)</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DualSense / DS5 (PlayStation 5)</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Nintendo Switch Pro</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Xbox 360</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Xbox One/Series</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" align="center"><b>GPU Encoding</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>AMD/AMF</td>
|
||||||
|
<td>✅ (vaapi)</td>
|
||||||
|
<td>✅ (vaapi)</td>
|
||||||
|
<td>✅ (Video Toolbox)</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Intel QuickSync</td>
|
||||||
|
<td>✅ (vaapi)</td>
|
||||||
|
<td>✅ (vaapi)</td>
|
||||||
|
<td>✅ (Video Toolbox)</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>NVIDIA NVENC</td>
|
||||||
|
<td>✅ (vaapi)</td>
|
||||||
|
<td>✅ (vaapi)</td>
|
||||||
|
<td>✅ (Video Toolbox)</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" align="center"><b>Screen Capture</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DXGI</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>KMS</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>NVIDIA NvFBC</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>🟡</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> ↳ X11 Support</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> ↳ Wayland Support</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>❌</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Video Toolbox</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Wayland</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Windows.Graphics.Capture</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>🟡</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> ↳ Portable</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>✅</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> ↳ Service</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>❌</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>X11</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>➖</td>
|
||||||
|
<td>➖</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
**Legend:** ✅ Supported | 🟡 Partial Support | ❌ Not Yet Supported | ➖ Not Applicable
|
||||||
|
|
||||||
## 🖥️ System Requirements
|
## 🖥️ System Requirements
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
|
|
@ -50,7 +210,7 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Intel:<br>
|
Intel:<br>
|
||||||
Linux: VAAPI-compatible, see: <a href="https://www.intel.com/content/www/us/en/developer/articles/technical/linuxmedia-vaapi.html">VAAPI hardware support</a><br>
|
FreeBSD/Linux: VAAPI-compatible, see: <a href="https://www.intel.com/content/www/us/en/developer/articles/technical/linuxmedia-vaapi.html">VAAPI hardware support</a><br>
|
||||||
Windows: Skylake or newer with QuickSync encoding support
|
Windows: Skylake or newer with QuickSync encoding support
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -69,11 +229,8 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
|
||||||
<td>4GB or more</td>
|
<td>4GB or more</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="5">OS</td>
|
<td rowspan="6">OS</td>
|
||||||
<td>Windows: 10+ (Windows Server does not support virtual gamepads)</td>
|
<td>FreeBSD: 14.3+</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>macOS: 14+</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Linux/Debian: 13+ (trixie)</td>
|
<td>Linux/Debian: 13+ (trixie)</td>
|
||||||
|
|
@ -84,6 +241,12 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
|
||||||
<tr>
|
<tr>
|
||||||
<td>Linux/Ubuntu: 22.04+ (jammy)</td>
|
<td>Linux/Ubuntu: 22.04+ (jammy)</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>macOS: 14+</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Windows: 11+ (Windows Server does not support virtual gamepads)</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2">Network</td>
|
<td rowspan="2">Network</td>
|
||||||
<td>Host: 5GHz, 802.11ac</td>
|
<td>Host: 5GHz, 802.11ac</td>
|
||||||
|
|
@ -106,14 +269,14 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Intel:<br>
|
Intel:<br>
|
||||||
Linux: HD Graphics 510 or higher<br>
|
FreeBSD/Linux: HD Graphics 510 or higher<br>
|
||||||
Windows: Skylake or newer with QuickSync encoding support
|
Windows: Skylake or newer with QuickSync encoding support
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Nvidia:<br>
|
Nvidia:<br>
|
||||||
Linux: GeForce RTX 2000 series or higher<br>
|
FreeBSD/Linux: GeForce RTX 2000 series or higher<br>
|
||||||
Windows: Geforce GTX 1080 or higher
|
Windows: Geforce GTX 1080 or higher
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
# linux specific compile definitions
|
# linux specific compile definitions
|
||||||
|
|
||||||
add_compile_definitions(SUNSHINE_PLATFORM="linux")
|
if(FREEBSD)
|
||||||
|
add_compile_definitions(SUNSHINE_PLATFORM="freebsd")
|
||||||
|
else()
|
||||||
|
add_compile_definitions(SUNSHINE_PLATFORM="linux")
|
||||||
|
endif()
|
||||||
|
|
||||||
# AppImage
|
# AppImage
|
||||||
if(${SUNSHINE_BUILD_APPIMAGE})
|
if(${SUNSHINE_BUILD_APPIMAGE})
|
||||||
|
|
@ -211,6 +215,9 @@ endif()
|
||||||
# These need to be set before adding the inputtino subdirectory in order for them to be picked up
|
# These need to be set before adding the inputtino subdirectory in order for them to be picked up
|
||||||
set(LIBEVDEV_CUSTOM_INCLUDE_DIR "${EVDEV_INCLUDE_DIR}")
|
set(LIBEVDEV_CUSTOM_INCLUDE_DIR "${EVDEV_INCLUDE_DIR}")
|
||||||
set(LIBEVDEV_CUSTOM_LIBRARY "${EVDEV_LIBRARY}")
|
set(LIBEVDEV_CUSTOM_LIBRARY "${EVDEV_LIBRARY}")
|
||||||
|
if(FREEBSD)
|
||||||
|
set(USE_UHID OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory("${CMAKE_SOURCE_DIR}/third-party/inputtino")
|
add_subdirectory("${CMAKE_SOURCE_DIR}/third-party/inputtino")
|
||||||
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES inputtino::libinputtino)
|
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES inputtino::libinputtino)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ include_directories(SYSTEM ${MINIUPNP_INCLUDE_DIRS})
|
||||||
if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
|
if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid vpl)
|
set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid vpl)
|
||||||
|
elseif(FREEBSD)
|
||||||
|
# numa is not available on FreeBSD
|
||||||
|
set(FFMPEG_PLATFORM_LIBRARIES va va-drm va-x11 X11)
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 X11)
|
set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 X11)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
138
cmake/packaging/freebsd_custom_cpack.cmake
Normal file
138
cmake/packaging/freebsd_custom_cpack.cmake
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
# FreeBSD post-build script to fix +POST_INSTALL and +PRE_DEINSTALL scripts
|
||||||
|
# in the generated .pkg file.
|
||||||
|
#
|
||||||
|
# This script runs AFTER CPack creates the .pkg file. We need to:
|
||||||
|
# 1. Extract the .pkg file (which is a tar.xz archive)
|
||||||
|
# 2. Add our install/deinstall scripts to the root
|
||||||
|
# 3. Remove script entries from the +MANIFEST files section
|
||||||
|
# 4. Repack the .pkg file using pkg-static
|
||||||
|
|
||||||
|
if(NOT CPACK_GENERATOR STREQUAL "FREEBSD")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "FreeBSD post-build: Processing install/deinstall scripts")
|
||||||
|
|
||||||
|
# Get script paths from the list we set
|
||||||
|
if(NOT DEFINED CPACK_FREEBSD_PACKAGE_SCRIPTS)
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: CPACK_FREEBSD_PACKAGE_SCRIPTS not defined")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(LENGTH CPACK_FREEBSD_PACKAGE_SCRIPTS _script_count)
|
||||||
|
if(_script_count EQUAL 0)
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: CPACK_FREEBSD_PACKAGE_SCRIPTS is empty")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Find the package file in CPACK_TOPLEVEL_DIRECTORY
|
||||||
|
file(GLOB _pkg_files "${CPACK_TOPLEVEL_DIRECTORY}/*.pkg")
|
||||||
|
|
||||||
|
if(NOT _pkg_files)
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: No .pkg file found in ${CPACK_TOPLEVEL_DIRECTORY}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(GET _pkg_files 0 _pkg_file)
|
||||||
|
message(STATUS "FreeBSD post-build: Found package: ${_pkg_file}")
|
||||||
|
|
||||||
|
# Create a temporary directory for extraction
|
||||||
|
get_filename_component(_pkg_dir "${_pkg_file}" DIRECTORY)
|
||||||
|
set(_tmp_dir "${_pkg_dir}/pkg_repack_tmp")
|
||||||
|
file(REMOVE_RECURSE "${_tmp_dir}")
|
||||||
|
file(MAKE_DIRECTORY "${_tmp_dir}")
|
||||||
|
|
||||||
|
# Extract the package using tar (pkg files are tar.xz archives)
|
||||||
|
message(STATUS "FreeBSD post-build: Extracting package...")
|
||||||
|
find_program(TAR_EXECUTABLE tar REQUIRED)
|
||||||
|
find_program(PKG_STATIC_EXECUTABLE pkg-static REQUIRED)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${TAR_EXECUTABLE} -xf ${_pkg_file} --no-same-owner --numeric-owner
|
||||||
|
WORKING_DIRECTORY "${_tmp_dir}"
|
||||||
|
RESULT_VARIABLE _extract_result
|
||||||
|
ERROR_VARIABLE _extract_error
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT _extract_result EQUAL 0)
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: Failed to extract package: ${_extract_error}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Debug: Check what was extracted
|
||||||
|
file(GLOB_RECURSE _extracted_files RELATIVE "${_tmp_dir}" "${_tmp_dir}/*")
|
||||||
|
list(LENGTH _extracted_files _file_count)
|
||||||
|
message(STATUS "FreeBSD post-build: Extracted ${_file_count} files")
|
||||||
|
|
||||||
|
# Copy the install/deinstall scripts to the extracted package root
|
||||||
|
message(STATUS "FreeBSD post-build: Adding install/deinstall scripts...")
|
||||||
|
|
||||||
|
foreach(script_path ${CPACK_FREEBSD_PACKAGE_SCRIPTS})
|
||||||
|
if(EXISTS "${script_path}")
|
||||||
|
get_filename_component(_script_name "${script_path}" NAME)
|
||||||
|
file(COPY "${script_path}"
|
||||||
|
DESTINATION "${_tmp_dir}/"
|
||||||
|
FILE_PERMISSIONS
|
||||||
|
OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||||
|
GROUP_READ GROUP_EXECUTE
|
||||||
|
WORLD_READ WORLD_EXECUTE)
|
||||||
|
message(STATUS " Added: ${_script_name}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: Script not found: ${script_path}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Repack the package using pkg-static create
|
||||||
|
message(STATUS "FreeBSD post-build: Repacking package...")
|
||||||
|
|
||||||
|
# Debug: Verify files before repacking
|
||||||
|
file(GLOB_RECURSE _files_before_repack RELATIVE "${_tmp_dir}" "${_tmp_dir}/*")
|
||||||
|
list(LENGTH _files_before_repack _count_before_repack)
|
||||||
|
message(STATUS "FreeBSD post-build: About to repack ${_count_before_repack} files")
|
||||||
|
|
||||||
|
# Debug: Check directory structure
|
||||||
|
if(EXISTS "${_tmp_dir}/usr")
|
||||||
|
message(STATUS "FreeBSD post-build: Found usr directory in extracted package")
|
||||||
|
file(GLOB_RECURSE _usr_files RELATIVE "${_tmp_dir}/usr" "${_tmp_dir}/usr/*")
|
||||||
|
list(LENGTH _usr_files _usr_file_count)
|
||||||
|
message(STATUS "FreeBSD post-build: usr directory contains ${_usr_file_count} files")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create metadata directory separate from rootdir
|
||||||
|
set(_metadata_dir "${_tmp_dir}/metadata")
|
||||||
|
file(MAKE_DIRECTORY "${_metadata_dir}")
|
||||||
|
|
||||||
|
# Move manifest and scripts to metadata directory
|
||||||
|
file(GLOB _metadata_files "${_tmp_dir}/+*")
|
||||||
|
foreach(meta_file ${_metadata_files})
|
||||||
|
get_filename_component(_meta_name "${meta_file}" NAME)
|
||||||
|
file(RENAME "${meta_file}" "${_metadata_dir}/${_meta_name}")
|
||||||
|
message(STATUS "FreeBSD post-build: Moved ${_meta_name} to metadata directory")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Use pkg-static create to rebuild the package
|
||||||
|
# pkg create -r rootdir -m manifestdir -o outdir
|
||||||
|
# The rootdir should contain the actual files (usr/local/...)
|
||||||
|
# The manifestdir should contain +MANIFEST and install scripts
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${PKG_STATIC_EXECUTABLE} create -r ${_tmp_dir} -m ${_metadata_dir} -o ${_pkg_dir}
|
||||||
|
RESULT_VARIABLE _pack_result
|
||||||
|
OUTPUT_VARIABLE _pack_output
|
||||||
|
ERROR_VARIABLE _pack_error
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT _pack_result EQUAL 0)
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: Failed to repack package: ${_pack_error}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Find the generated package file (pkg create generates its own name based on manifest)
|
||||||
|
file(GLOB _new_pkg_files "${_pkg_dir}/Sunshine-*.pkg")
|
||||||
|
if(NOT _new_pkg_files)
|
||||||
|
message(FATAL_ERROR "FreeBSD post-build: pkg-static create succeeded but no package file was generated")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(GET _new_pkg_files 0 _generated_pkg)
|
||||||
|
|
||||||
|
# Replace the original package with the newly created one
|
||||||
|
file(REMOVE "${_pkg_file}")
|
||||||
|
file(RENAME "${_generated_pkg}" "${_pkg_file}")
|
||||||
|
message(STATUS "FreeBSD post-build: Successfully processed package")
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
file(REMOVE_RECURSE "${_tmp_dir}")
|
||||||
|
|
@ -34,10 +34,34 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# RPM specific
|
||||||
|
set(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
|
||||||
|
|
||||||
|
# FreeBSD specific
|
||||||
|
set(CPACK_FREEBSD_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}")
|
||||||
|
set(CPACK_FREEBSD_PACKAGE_ORIGIN "misc/${CPACK_PACKAGE_NAME}")
|
||||||
|
set(CPACK_FREEBSD_PACKAGE_LICENSE "GPLv3")
|
||||||
|
|
||||||
# Post install
|
# Post install
|
||||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
|
||||||
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
|
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst")
|
||||||
|
|
||||||
|
# FreeBSD post install/deinstall scripts
|
||||||
|
if(FREEBSD)
|
||||||
|
# Note: CPack's FreeBSD generator does NOT natively support install/deinstall scripts
|
||||||
|
# like CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA or CPACK_RPM_POST_INSTALL_SCRIPT_FILE.
|
||||||
|
# This is a known limitation of the CPack FREEBSD generator.
|
||||||
|
#
|
||||||
|
# Workaround: Use CPACK_POST_BUILD_SCRIPTS to extract the generated .pkg file,
|
||||||
|
# add the install/deinstall scripts, and repack the package. This ensures they are
|
||||||
|
# recognized as package control scripts rather than installed files.
|
||||||
|
set(CPACK_FREEBSD_PACKAGE_SCRIPTS
|
||||||
|
"${SUNSHINE_SOURCE_ASSETS_DIR}/bsd/misc/+POST_INSTALL"
|
||||||
|
"${SUNSHINE_SOURCE_ASSETS_DIR}/bsd/misc/+PRE_DEINSTALL"
|
||||||
|
)
|
||||||
|
list(APPEND CPACK_POST_BUILD_SCRIPTS "${CMAKE_MODULE_PATH}/packaging/freebsd_custom_cpack.cmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Apply setcap for RPM
|
# Apply setcap for RPM
|
||||||
# https://github.com/coreos/rpm-ostree/discussions/5036#discussioncomment-10291071
|
# https://github.com/coreos/rpm-ostree/discussions/5036#discussioncomment-10291071
|
||||||
set(CPACK_RPM_USER_FILELIST "%caps(cap_sys_admin+p) ${SUNSHINE_EXECUTABLE_PATH}")
|
set(CPACK_RPM_USER_FILELIST "%caps(cap_sys_admin+p) ${SUNSHINE_EXECUTABLE_PATH}")
|
||||||
|
|
@ -77,6 +101,15 @@ set(CPACK_RPM_PACKAGE_REQUIRES "\
|
||||||
openssl >= 3.0.2, \
|
openssl >= 3.0.2, \
|
||||||
pulseaudio-libs >= 10.0, \
|
pulseaudio-libs >= 10.0, \
|
||||||
which >= 2.21")
|
which >= 2.21")
|
||||||
|
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||||
|
audio/opus
|
||||||
|
ftp/curl
|
||||||
|
devel/libevdev
|
||||||
|
net/avahi
|
||||||
|
x11/libX11
|
||||||
|
net/miniupnpc
|
||||||
|
security/openssl
|
||||||
|
)
|
||||||
|
|
||||||
if(NOT BOOST_USE_STATIC)
|
if(NOT BOOST_USE_STATIC)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
|
||||||
|
|
@ -91,6 +124,9 @@ if(NOT BOOST_USE_STATIC)
|
||||||
boost-locale >= ${Boost_VERSION}, \
|
boost-locale >= ${Boost_VERSION}, \
|
||||||
boost-log >= ${Boost_VERSION}, \
|
boost-log >= ${Boost_VERSION}, \
|
||||||
boost-program-options >= ${Boost_VERSION}")
|
boost-program-options >= ${Boost_VERSION}")
|
||||||
|
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||||
|
devel/boost-libs
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# This should automatically figure out dependencies on packages
|
# This should automatically figure out dependencies on packages
|
||||||
|
|
@ -142,6 +178,10 @@ if(${SUNSHINE_TRAY} STREQUAL 1)
|
||||||
set(CPACK_RPM_PACKAGE_REQUIRES "\
|
set(CPACK_RPM_PACKAGE_REQUIRES "\
|
||||||
${CPACK_RPM_PACKAGE_REQUIRES}, \
|
${CPACK_RPM_PACKAGE_REQUIRES}, \
|
||||||
libappindicator-gtk3 >= 12.10.0")
|
libappindicator-gtk3 >= 12.10.0")
|
||||||
|
list(APPEND CPACK_FREEBSD_PACKAGE_DEPS
|
||||||
|
devel/libayatana-appindicator
|
||||||
|
devel/libnotify
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# desktop file
|
# desktop file
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,14 @@ and applications to Sunshine.
|
||||||
> process is killed.
|
> process is killed.
|
||||||
|
|
||||||
@tabs{
|
@tabs{
|
||||||
|
@tab{FreeBSD | <!-- -->
|
||||||
|
\| Field \| Value \|
|
||||||
|
\|------------------------------\|------------------------------------------------------\|
|
||||||
|
\| Application Name \| @code{}Steam Big Picture@endcode \|
|
||||||
|
\| Command Preporations -> Undo \| @code{}setsid steam steam://close/bigpicture@endcode \|
|
||||||
|
\| Detached Commands \| @code{}setsid steam steam://open/bigpicture@endcode \|
|
||||||
|
\| Image \| @code{}steam.png@endcode \|
|
||||||
|
}
|
||||||
@tab{Linux | <!-- -->
|
@tab{Linux | <!-- -->
|
||||||
\| Field \| Value \|
|
\| Field \| Value \|
|
||||||
\|------------------------------\|------------------------------------------------------\|
|
\|------------------------------\|------------------------------------------------------\|
|
||||||
|
|
@ -97,6 +105,12 @@ and applications to Sunshine.
|
||||||
#### URI
|
#### URI
|
||||||
|
|
||||||
@tabs{
|
@tabs{
|
||||||
|
@tab{FreeBSD | <!-- -->
|
||||||
|
\| Field \| Value \|
|
||||||
|
\|-------------------\|------------------------------------------------------\|
|
||||||
|
\| Application Name \| @code{}Surviving Mars@endcode \|
|
||||||
|
\| Detached Commands \| @code{}setsid steam steam://rungameid/464920@endcode \|
|
||||||
|
}
|
||||||
@tab{Linux | <!-- -->
|
@tab{Linux | <!-- -->
|
||||||
\| Field \| Value \|
|
\| Field \| Value \|
|
||||||
\|-------------------\|------------------------------------------------------\|
|
\|-------------------\|------------------------------------------------------\|
|
||||||
|
|
@ -119,6 +133,13 @@ and applications to Sunshine.
|
||||||
|
|
||||||
#### Binary (w/ working directory
|
#### Binary (w/ working directory
|
||||||
@tabs{
|
@tabs{
|
||||||
|
@tab{FreeBSD | <!-- -->
|
||||||
|
\| Field \| Value \|
|
||||||
|
\|-------------------\|--------------------------------------------------------------\|
|
||||||
|
\| Application Name \| @code{}Surviving Mars@endcode \|
|
||||||
|
\| Command \| @code{}MarsSteam@endcode \|
|
||||||
|
\| Working Directory \| @code{}~/.steam/steam/SteamApps/common/Survivng Mars@endcode \|
|
||||||
|
}
|
||||||
@tab{Linux | <!-- -->
|
@tab{Linux | <!-- -->
|
||||||
\| Field \| Value \|
|
\| Field \| Value \|
|
||||||
\|-------------------\|--------------------------------------------------------------\|
|
\|-------------------\|--------------------------------------------------------------\|
|
||||||
|
|
@ -144,6 +165,12 @@ and applications to Sunshine.
|
||||||
|
|
||||||
#### Binary (w/o working directory)
|
#### Binary (w/o working directory)
|
||||||
@tabs{
|
@tabs{
|
||||||
|
@tab{FreeBSD | <!-- -->
|
||||||
|
\| Field \| Value \|
|
||||||
|
\|-------------------\|------------------------------------------------------------------------\|
|
||||||
|
\| Application Name \| @code{}Surviving Mars@endcode \|
|
||||||
|
\| Command \| @code{}~/.steam/steam/SteamApps/common/Survivng Mars/MarsSteam@endcode \|
|
||||||
|
}
|
||||||
@tab{Linux | <!-- -->
|
@tab{Linux | <!-- -->
|
||||||
\| Field \| Value \|
|
\| Field \| Value \|
|
||||||
\|-------------------\|------------------------------------------------------------------------\|
|
\|-------------------\|------------------------------------------------------------------------\|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,39 @@ It is recommended to use one of the following compilers:
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
|
#### FreeBSD
|
||||||
|
> [!CAUTION]
|
||||||
|
> Sunshine support for FreeBSD is experimental and may be incomplete or not work as expected
|
||||||
|
|
||||||
|
##### Install dependencies
|
||||||
|
```sh
|
||||||
|
pkg install -y \
|
||||||
|
audio/opus \
|
||||||
|
audio/pulseaudio \
|
||||||
|
devel/cmake \
|
||||||
|
devel/evdev-proto \
|
||||||
|
devel/git \
|
||||||
|
devel/libayatana-appindicator \
|
||||||
|
devel/libevdev \
|
||||||
|
devel/libnotify \
|
||||||
|
devel/ninja \
|
||||||
|
devel/pkgconf \
|
||||||
|
ftp/curl \
|
||||||
|
graphics/libdrm \
|
||||||
|
graphics/wayland \
|
||||||
|
multimedia/libva \
|
||||||
|
net/miniupnpc \
|
||||||
|
ports-mgmt/pkg \
|
||||||
|
security/openssl \
|
||||||
|
shells/bash \
|
||||||
|
www/npm \
|
||||||
|
x11/libX11 \
|
||||||
|
x11/libxcb \
|
||||||
|
x11/libXfixes \
|
||||||
|
x11/libXrandr \
|
||||||
|
x11/libXtst
|
||||||
|
```
|
||||||
|
|
||||||
#### Linux
|
#### Linux
|
||||||
Dependencies vary depending on the distribution. You can reference our
|
Dependencies vary depending on the distribution. You can reference our
|
||||||
[linux_build.sh](https://github.com/LizardByte/Sunshine/blob/master/scripts/linux_build.sh) script for a list of
|
[linux_build.sh](https://github.com/LizardByte/Sunshine/blob/master/scripts/linux_build.sh) script for a list of
|
||||||
|
|
@ -135,6 +168,11 @@ ninja -C build
|
||||||
### Package
|
### Package
|
||||||
|
|
||||||
@tabs{
|
@tabs{
|
||||||
|
@tab{FreeBSD | @tabs{
|
||||||
|
@tab{pkg | ```bash
|
||||||
|
cpack -G FREEBSD --config ./build/CPackConfig.cmake
|
||||||
|
```}
|
||||||
|
}}
|
||||||
@tab{Linux | @tabs{
|
@tab{Linux | @tabs{
|
||||||
@tab{deb | ```bash
|
@tab{deb | ```bash
|
||||||
cpack -G DEB --config ./build/CPackConfig.cmake
|
cpack -G DEB --config ./build/CPackConfig.cmake
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ location by modifying the configuration file.
|
||||||
| OS | Location |
|
| OS | Location |
|
||||||
|---------|-------------------------------------------------|
|
|---------|-------------------------------------------------|
|
||||||
| Docker | @code{}/config@endcode |
|
| Docker | @code{}/config@endcode |
|
||||||
|
| FreeBSD | @code{}~/.config/sunshine@endcode |
|
||||||
| Linux | @code{}~/.config/sunshine@endcode |
|
| Linux | @code{}~/.config/sunshine@endcode |
|
||||||
| macOS | @code{}~/.config/sunshine@endcode |
|
| macOS | @code{}~/.config/sunshine@endcode |
|
||||||
| Windows | @code{}%ProgramFiles%\\Sunshine\\config@endcode |
|
| Windows | @code{}%ProgramFiles%\\Sunshine\\config@endcode |
|
||||||
|
|
@ -339,12 +340,12 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
<tr>
|
<tr>
|
||||||
<td>ds5</td>
|
<td>ds5</td>
|
||||||
<td>DualShock 5 controller (PS5)
|
<td>DualShock 5 controller (PS5)
|
||||||
@note{This option applies to Linux only.}</td>
|
@note{This option applies to FreeBSD and Linux only.}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>switch</td>
|
<td>switch</td>
|
||||||
<td>Switch Pro controller
|
<td>Switch Pro controller
|
||||||
@note{This option applies to Linux only.}</td>
|
@note{This option applies to FreeBSD and Linux only.}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>x360</td>
|
<td>x360</td>
|
||||||
|
|
@ -354,7 +355,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
<tr>
|
<tr>
|
||||||
<td>xone</td>
|
<td>xone</td>
|
||||||
<td>Xbox One controller
|
<td>Xbox One controller
|
||||||
@note{This option applies to Linux only.}</td>
|
@note{This option applies to FreeBSD and Linux only.}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
@ -735,14 +736,14 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
@tip{To find the name of the audio sink follow these instructions.
|
@tip{To find the name of the audio sink follow these instructions.
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
**Linux + pulseaudio:**
|
**FreeBSD/Linux + pulseaudio:**
|
||||||
<br>
|
<br>
|
||||||
@code{}
|
@code{}
|
||||||
pacmd list-sinks | grep "name:"
|
pacmd list-sinks | grep "name:"
|
||||||
@endcode
|
@endcode
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
**Linux + pipewire:**
|
**FreeBSD/Linux + pipewire:**
|
||||||
<br>
|
<br>
|
||||||
@code{}
|
@code{}
|
||||||
pactl info | grep Source
|
pactl info | grep Source
|
||||||
|
|
@ -776,7 +777,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
<td colspan="2">Sunshine will select the default audio device.</td>
|
<td colspan="2">Sunshine will select the default audio device.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Example (Linux)</td>
|
<td>Example (FreeBSD/Linux)</td>
|
||||||
<td colspan="2">@code{}
|
<td colspan="2">@code{}
|
||||||
audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo
|
audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo
|
||||||
@endcode</td>
|
@endcode</td>
|
||||||
|
|
@ -883,7 +884,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
@tip{To find the appropriate values follow these instructions.
|
@tip{To find the appropriate values follow these instructions.
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
**Linux + VA-API:**
|
**FreeBSD/Linux + VA-API:**
|
||||||
<br>
|
<br>
|
||||||
Unlike with *amdvce* and *nvenc*, it doesn't matter if video encoding is done on a different GPU.
|
Unlike with *amdvce* and *nvenc*, it doesn't matter if video encoding is done on a different GPU.
|
||||||
@code{}
|
@code{}
|
||||||
|
|
@ -913,7 +914,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
<td colspan="2">Sunshine will select the default video card.</td>
|
<td colspan="2">Sunshine will select the default video card.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Example (Linux)</td>
|
<td>Example (FreeBSD/Linux)</td>
|
||||||
<td colspan="2">@code{}
|
<td colspan="2">@code{}
|
||||||
adapter_name = /dev/dri/renderD128
|
adapter_name = /dev/dri/renderD128
|
||||||
@endcode</td>
|
@endcode</td>
|
||||||
|
|
@ -936,7 +937,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
@tip{To find the appropriate values follow these instructions.
|
@tip{To find the appropriate values follow these instructions.
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
**Linux:**
|
**FreeBSD/Linux:**
|
||||||
<br>
|
<br>
|
||||||
During Sunshine startup, you should see the list of detected displays:
|
During Sunshine startup, you should see the list of detected displays:
|
||||||
@code{}
|
@code{}
|
||||||
|
|
@ -1021,7 +1022,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
<td colspan="2">Sunshine will select the default display.</td>
|
<td colspan="2">Sunshine will select the default display.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Example (Linux)</td>
|
<td>Example (FreeBSD/Linux)</td>
|
||||||
<td colspan="2">@code{}
|
<td colspan="2">@code{}
|
||||||
output_name = 0
|
output_name = 0
|
||||||
@endcode</td>
|
@endcode</td>
|
||||||
|
|
@ -2034,7 +2035,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
<tr>
|
<tr>
|
||||||
<td>x11</td>
|
<td>x11</td>
|
||||||
<td>Uses XCB. This is the slowest and most CPU intensive so should be avoided if possible.
|
<td>Uses XCB. This is the slowest and most CPU intensive so should be avoided if possible.
|
||||||
@note{Applies to Linux only.}</td>
|
@note{Applies to FreeBSD and Linux only.}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>ddx</td>
|
<td>ddx</td>
|
||||||
|
|
@ -2083,7 +2084,7 @@ editing the `conf` file in a text editor. Use the examples as reference.
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>vaapi</td>
|
<td>vaapi</td>
|
||||||
<td>Use Linux VA-API (AMD, Intel)</td>
|
<td>Use VA-API (AMD, Intel)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>software</td>
|
<td>software</td>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ and release artifacts may be missing when merging changes on a faster cadence.
|
||||||
|
|
||||||
## Binaries
|
## Binaries
|
||||||
|
|
||||||
Binaries of Sunshine are created for each release. They are available for Linux, macOS, and Windows.
|
Binaries of Sunshine are created for each release. They are available for FreeBSD, Linux, macOS, and Windows.
|
||||||
Binaries can be found in the [latest release][latest-release].
|
Binaries can be found in the [latest release][latest-release].
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
|
@ -28,7 +28,28 @@ and [ghcr.io](https://github.com/orgs/LizardByte/packages?repo_name=sunshine).
|
||||||
|
|
||||||
See [Docker](../DOCKER_README.md) for more information.
|
See [Docker](../DOCKER_README.md) for more information.
|
||||||
|
|
||||||
|
### FreeBSD
|
||||||
|
|
||||||
|
#### Install
|
||||||
|
1. Download the appropriate package for your architecture
|
||||||
|
|
||||||
|
| Architecture | Package |
|
||||||
|
|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| amd64/x86_64 | [Sunshine-FreeBSD-14.3-amd64.pkg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-FreeBSD-14.3-amd64.pkg) |
|
||||||
|
| arm64/aarch64 | [Sunshine-FreeBSD-14.3-aarch64.pkg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-FreeBSD-14.3-aarch64.pkg) |
|
||||||
|
|
||||||
|
2. Open terminal and run the following command.
|
||||||
|
```sh
|
||||||
|
sudo pkg install ./Sunshine-FreeBSD-14.3-{arch}.pkg
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Uninstall
|
||||||
|
```sh
|
||||||
|
sudo pkg delete Sunshine
|
||||||
|
```
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
**CUDA Compatibility**
|
**CUDA Compatibility**
|
||||||
|
|
||||||
CUDA is used for NVFBC capture.
|
CUDA is used for NVFBC capture.
|
||||||
|
|
@ -380,6 +401,22 @@ overflow menu. Different versions of Windows may provide slightly different step
|
||||||
## Initial Setup
|
## Initial Setup
|
||||||
After installation, some initial setup is required.
|
After installation, some initial setup is required.
|
||||||
|
|
||||||
|
### FreeBSD
|
||||||
|
|
||||||
|
#### Virtual Input Devices
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> To use virtual input devices (keyboard, mouse, gamepads), you must add your user to the `input` group.
|
||||||
|
|
||||||
|
The installation process creates the `input` group and configures permissions for `/dev/uinput`.
|
||||||
|
To allow your user to create virtual input devices, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pw groupmod input -m $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
After adding yourself to the group, log out and log back in for the changes to take effect.
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
#### KMS Capture
|
#### KMS Capture
|
||||||
|
|
@ -542,7 +579,16 @@ All shortcuts start with `Ctrl+Alt+Shift`, just like Moonlight.
|
||||||
instead it simply starts a stream. If you removed it and would like to get it back, just add a new application with
|
instead it simply starts a stream. If you removed it and would like to get it back, just add a new application with
|
||||||
the name "Desktop" and "desktop.png" as the image path.
|
the name "Desktop" and "desktop.png" as the image path.
|
||||||
* For the Linux flatpak you must prepend commands with `flatpak-spawn --host`.
|
* For the Linux flatpak you must prepend commands with `flatpak-spawn --host`.
|
||||||
* If inputs (mouse, keyboard, gamepads...) aren't working after connecting, add the user running sunshine to the `input` group.
|
* If inputs (mouse, keyboard, gamepads...) aren't working after connecting:
|
||||||
|
|
||||||
|
* On FreeBSD/Linux, add the user running sunshine to the `input` group.
|
||||||
|
|
||||||
|
* The FreeBSD version of Sunshine is missing some features that are present on Linux.
|
||||||
|
The following are known limitations.
|
||||||
|
|
||||||
|
* Only X11 and Wayland capture are supported
|
||||||
|
* DualSense/DS5 emulation is not available due to missing uhid features
|
||||||
|
|
||||||
|
|
||||||
### HDR Support
|
### HDR Support
|
||||||
Streaming HDR content is officially supported on Windows hosts and experimentally supported for Linux hosts.
|
Streaming HDR content is officially supported on Windows hosts and experimentally supported for Linux hosts.
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,22 @@
|
||||||
|
|
||||||
// standard includes
|
// standard includes
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// platform includes
|
// platform includes
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <netinet/udp.h>
|
#include <netinet/udp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <net/if_dl.h> // For sockaddr_dl, LLADDR, and AF_LINK
|
||||||
|
#endif
|
||||||
|
|
||||||
// lib includes
|
// lib includes
|
||||||
#include <boost/asio/ip/address.hpp>
|
#include <boost/asio/ip/address.hpp>
|
||||||
|
|
@ -41,6 +49,16 @@
|
||||||
#define SUNSHINE_GNUC_EXTENSION
|
#define SUNSHINE_GNUC_EXTENSION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SOL_IP
|
||||||
|
#define SOL_IP IPPROTO_IP
|
||||||
|
#endif
|
||||||
|
#ifndef SOL_IPV6
|
||||||
|
#define SOL_IPV6 IPPROTO_IPV6
|
||||||
|
#endif
|
||||||
|
#ifndef SOL_UDP
|
||||||
|
#define SOL_UDP IPPROTO_UDP
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
namespace bp = boost::process::v1;
|
namespace bp = boost::process::v1;
|
||||||
|
|
@ -214,6 +232,40 @@ namespace platf {
|
||||||
|
|
||||||
std::string get_mac_address(const std::string_view &address) {
|
std::string get_mac_address(const std::string_view &address) {
|
||||||
auto ifaddrs = get_ifaddrs();
|
auto ifaddrs = get_ifaddrs();
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
// On FreeBSD, we need to find the interface name first, then look for its AF_LINK entry
|
||||||
|
std::string interface_name;
|
||||||
|
for (auto pos = ifaddrs.get(); pos != nullptr; pos = pos->ifa_next) {
|
||||||
|
if (pos->ifa_addr && address == from_sockaddr(pos->ifa_addr)) {
|
||||||
|
interface_name = pos->ifa_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface_name.empty()) {
|
||||||
|
// Find the AF_LINK entry for this interface to get MAC address
|
||||||
|
for (auto pos = ifaddrs.get(); pos != nullptr; pos = pos->ifa_next) {
|
||||||
|
if (pos->ifa_addr && pos->ifa_addr->sa_family == AF_LINK &&
|
||||||
|
interface_name == pos->ifa_name) {
|
||||||
|
auto sdl = (struct sockaddr_dl *) pos->ifa_addr;
|
||||||
|
auto mac = (unsigned char *) LLADDR(sdl);
|
||||||
|
|
||||||
|
// Format MAC address as XX:XX:XX:XX:XX:XX
|
||||||
|
std::ostringstream mac_stream;
|
||||||
|
mac_stream << std::hex << std::setfill('0');
|
||||||
|
for (int i = 0; i < sdl->sdl_alen; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
mac_stream << ':';
|
||||||
|
}
|
||||||
|
mac_stream << std::setw(2) << (int) mac[i];
|
||||||
|
}
|
||||||
|
return mac_stream.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// On Linux, read MAC address from sysfs
|
||||||
for (auto pos = ifaddrs.get(); pos != nullptr; pos = pos->ifa_next) {
|
for (auto pos = ifaddrs.get(); pos != nullptr; pos = pos->ifa_next) {
|
||||||
if (pos->ifa_addr && address == from_sockaddr(pos->ifa_addr)) {
|
if (pos->ifa_addr && address == from_sockaddr(pos->ifa_addr)) {
|
||||||
std::ifstream mac_file("/sys/class/net/"s + pos->ifa_name + "/address");
|
std::ifstream mac_file("/sys/class/net/"s + pos->ifa_name + "/address");
|
||||||
|
|
@ -224,6 +276,7 @@ namespace platf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_LOG(warning) << "Unable to find MAC address for "sv << address;
|
BOOST_LOG(warning) << "Unable to find MAC address for "sv << address;
|
||||||
return "00:00:00:00:00:00"s;
|
return "00:00:00:00:00:00"s;
|
||||||
|
|
@ -377,7 +430,12 @@ namespace platf {
|
||||||
}
|
}
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
char buf[CMSG_SPACE(sizeof(uint16_t)) + std::max(CMSG_SPACE(sizeof(struct in_pktinfo)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
char buf[CMSG_SPACE(sizeof(uint16_t)) + std::max(CMSG_SPACE(sizeof(struct in_pktinfo)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||||
|
#elif defined(IP_SENDSRCADDR)
|
||||||
|
// FreeBSD uses IP_SENDSRCADDR with struct in_addr instead of IP_PKTINFO with struct in_pktinfo
|
||||||
|
char buf[CMSG_SPACE(sizeof(uint16_t)) + std::max(CMSG_SPACE(sizeof(struct in_addr)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||||
|
#endif
|
||||||
struct cmsghdr alignment;
|
struct cmsghdr alignment;
|
||||||
} cmbuf = {}; // Must be zeroed for CMSG_NXTHDR()
|
} cmbuf = {}; // Must be zeroed for CMSG_NXTHDR()
|
||||||
|
|
||||||
|
|
@ -403,6 +461,7 @@ namespace platf {
|
||||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
struct in_pktinfo pktInfo;
|
struct in_pktinfo pktInfo;
|
||||||
|
|
||||||
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||||
|
|
@ -415,6 +474,18 @@ namespace platf {
|
||||||
pktinfo_cm->cmsg_type = IP_PKTINFO;
|
pktinfo_cm->cmsg_type = IP_PKTINFO;
|
||||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||||
|
#elif defined(IP_SENDSRCADDR)
|
||||||
|
// FreeBSD uses IP_SENDSRCADDR with struct in_addr instead of IP_PKTINFO
|
||||||
|
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||||
|
struct in_addr src_addr = saddr_v4.sin_addr;
|
||||||
|
|
||||||
|
cmbuflen += CMSG_SPACE(sizeof(src_addr));
|
||||||
|
|
||||||
|
pktinfo_cm->cmsg_level = IPPROTO_IP;
|
||||||
|
pktinfo_cm->cmsg_type = IP_SENDSRCADDR;
|
||||||
|
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(src_addr));
|
||||||
|
memcpy(CMSG_DATA(pktinfo_cm), &src_addr, sizeof(src_addr));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const max_iovs_per_msg = send_info.payload_buffers.size() + (send_info.headers ? 1 : 0);
|
auto const max_iovs_per_msg = send_info.payload_buffers.size() + (send_info.headers ? 1 : 0);
|
||||||
|
|
@ -507,8 +578,8 @@ namespace platf {
|
||||||
|
|
||||||
{
|
{
|
||||||
// If GSO is not supported, use sendmmsg() instead.
|
// If GSO is not supported, use sendmmsg() instead.
|
||||||
struct mmsghdr msgs[send_info.block_count];
|
std::vector<struct mmsghdr> msgs(send_info.block_count);
|
||||||
struct iovec iovs[send_info.block_count * (send_info.headers ? 2 : 1)];
|
std::vector<struct iovec> iovs(send_info.block_count * (send_info.headers ? 2 : 1));
|
||||||
int iov_idx = 0;
|
int iov_idx = 0;
|
||||||
for (size_t i = 0; i < send_info.block_count; i++) {
|
for (size_t i = 0; i < send_info.block_count; i++) {
|
||||||
msgs[i].msg_len = 0;
|
msgs[i].msg_len = 0;
|
||||||
|
|
@ -584,7 +655,12 @@ namespace platf {
|
||||||
}
|
}
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
char buf[std::max(CMSG_SPACE(sizeof(struct in_pktinfo)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
char buf[std::max(CMSG_SPACE(sizeof(struct in_pktinfo)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||||
|
#elif defined(IP_SENDSRCADDR)
|
||||||
|
// FreeBSD uses IP_SENDSRCADDR with struct in_addr instead of IP_PKTINFO with struct in_pktinfo
|
||||||
|
char buf[std::max(CMSG_SPACE(sizeof(struct in_addr)), CMSG_SPACE(sizeof(struct in6_pktinfo)))];
|
||||||
|
#endif
|
||||||
struct cmsghdr alignment;
|
struct cmsghdr alignment;
|
||||||
} cmbuf;
|
} cmbuf;
|
||||||
|
|
||||||
|
|
@ -608,6 +684,7 @@ namespace platf {
|
||||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef IP_PKTINFO
|
||||||
struct in_pktinfo pktInfo;
|
struct in_pktinfo pktInfo;
|
||||||
|
|
||||||
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||||
|
|
@ -620,6 +697,18 @@ namespace platf {
|
||||||
pktinfo_cm->cmsg_type = IP_PKTINFO;
|
pktinfo_cm->cmsg_type = IP_PKTINFO;
|
||||||
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||||
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
memcpy(CMSG_DATA(pktinfo_cm), &pktInfo, sizeof(pktInfo));
|
||||||
|
#elif defined(IP_SENDSRCADDR)
|
||||||
|
// FreeBSD uses IP_SENDSRCADDR with struct in_addr instead of IP_PKTINFO
|
||||||
|
struct sockaddr_in saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
|
||||||
|
struct in_addr src_addr = saddr_v4.sin_addr;
|
||||||
|
|
||||||
|
cmbuflen += CMSG_SPACE(sizeof(src_addr));
|
||||||
|
|
||||||
|
pktinfo_cm->cmsg_level = IPPROTO_IP;
|
||||||
|
pktinfo_cm->cmsg_type = IP_SENDSRCADDR;
|
||||||
|
pktinfo_cm->cmsg_len = CMSG_LEN(sizeof(src_addr));
|
||||||
|
memcpy(CMSG_DATA(pktinfo_cm), &src_addr, sizeof(src_addr));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct iovec iovs[2];
|
struct iovec iovs[2];
|
||||||
|
|
@ -753,6 +842,10 @@ namespace platf {
|
||||||
// reset SO_PRIORITY back to 0.
|
// reset SO_PRIORITY back to 0.
|
||||||
//
|
//
|
||||||
// 6 is the highest priority that can be used without SYS_CAP_ADMIN.
|
// 6 is the highest priority that can be used without SYS_CAP_ADMIN.
|
||||||
|
#ifndef SO_PRIORITY
|
||||||
|
// FreeBSD doesn't support SO_PRIORITY, so we skip this
|
||||||
|
BOOST_LOG(debug) << "SO_PRIORITY not supported on this platform, skipping traffic priority setting";
|
||||||
|
#else
|
||||||
int priority = data_type == qos_data_type_e::audio ? 6 : 5;
|
int priority = data_type == qos_data_type_e::audio ? 6 : 5;
|
||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) == 0) {
|
if (setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &priority, sizeof(priority)) == 0) {
|
||||||
// Reset SO_PRIORITY to 0 when QoS is disabled
|
// Reset SO_PRIORITY to 0 when QoS is disabled
|
||||||
|
|
@ -760,6 +853,7 @@ namespace platf {
|
||||||
} else {
|
} else {
|
||||||
BOOST_LOG(error) << "Failed to set SO_PRIORITY: "sv << errno;
|
BOOST_LOG(error) << "Failed to set SO_PRIORITY: "sv << errno;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return std::make_unique<qos_t>(sockfd, reset_options);
|
return std::make_unique<qos_t>(sockfd, reset_options);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -520,7 +520,12 @@ namespace stream {
|
||||||
// for other communications to the client. This is necessary to ensure
|
// for other communications to the client. This is necessary to ensure
|
||||||
// proper routing on multi-homed hosts.
|
// proper routing on multi-homed hosts.
|
||||||
auto local_address = platf::from_sockaddr((sockaddr *) &peer->localAddress.address);
|
auto local_address = platf::from_sockaddr((sockaddr *) &peer->localAddress.address);
|
||||||
|
try {
|
||||||
session_p->localAddress = boost::asio::ip::make_address(local_address);
|
session_p->localAddress = boost::asio::ip::make_address(local_address);
|
||||||
|
} catch (const boost::system::system_error &e) {
|
||||||
|
BOOST_LOG(error) << "boost::system::system_error in address parsing: " << e.what() << " (code: " << e.code() << ")"sv;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_LOG(debug) << "Control local address ["sv << local_address << ']';
|
BOOST_LOG(debug) << "Control local address ["sv << local_address << ']';
|
||||||
BOOST_LOG(debug) << "Control peer address ["sv << peer_addr << ':' << peer_port << ']';
|
BOOST_LOG(debug) << "Control peer address ["sv << peer_addr << ':' << peer_port << ']';
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing.ico"
|
#define TRAY_ICON_PLAYING WEB_DIR "images/sunshine-playing.ico"
|
||||||
#define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico"
|
#define TRAY_ICON_PAUSING WEB_DIR "images/sunshine-pausing.ico"
|
||||||
#define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico"
|
#define TRAY_ICON_LOCKED WEB_DIR "images/sunshine-locked.ico"
|
||||||
#elif defined(__linux__) || defined(linux) || defined(__linux)
|
#elif defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||||
#define TRAY_ICON SUNSHINE_TRAY_PREFIX "-tray"
|
#define TRAY_ICON SUNSHINE_TRAY_PREFIX "-tray"
|
||||||
#define TRAY_ICON_PLAYING SUNSHINE_TRAY_PREFIX "-playing"
|
#define TRAY_ICON_PLAYING SUNSHINE_TRAY_PREFIX "-playing"
|
||||||
#define TRAY_ICON_PAUSING SUNSHINE_TRAY_PREFIX "-pausing"
|
#define TRAY_ICON_PAUSING SUNSHINE_TRAY_PREFIX "-pausing"
|
||||||
|
|
|
||||||
|
|
@ -897,7 +897,7 @@ namespace video {
|
||||||
H264_ONLY | PARALLEL_ENCODING | ALWAYS_REPROBE | YUV444_SUPPORT
|
H264_ONLY | PARALLEL_ENCODING | ALWAYS_REPROBE | YUV444_SUPPORT
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||||
encoder_t vaapi {
|
encoder_t vaapi {
|
||||||
"vaapi"sv,
|
"vaapi"sv,
|
||||||
std::make_unique<encoder_platform_formats_avcodec>(
|
std::make_unique<encoder_platform_formats_avcodec>(
|
||||||
|
|
@ -1032,7 +1032,7 @@ namespace video {
|
||||||
&quicksync,
|
&quicksync,
|
||||||
&amdvce,
|
&amdvce,
|
||||||
#endif
|
#endif
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||||
&vaapi,
|
&vaapi,
|
||||||
#endif
|
#endif
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ namespace video {
|
||||||
extern encoder_t quicksync;
|
extern encoder_t quicksync;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)
|
||||||
extern encoder_t vaapi;
|
extern encoder_t vaapi;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
64
src_assets/bsd/misc/+POST_INSTALL
Normal file
64
src_assets/bsd/misc/+POST_INSTALL
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# FreeBSD post-install script for Sunshine
|
||||||
|
# This script sets up the necessary permissions for virtual input devices
|
||||||
|
|
||||||
|
echo "Configuring permissions for virtual input devices..."
|
||||||
|
|
||||||
|
# Create the 'input' group if it doesn't exist
|
||||||
|
if ! pw groupshow input >/dev/null 2>&1; then
|
||||||
|
echo "Creating 'input' group..."
|
||||||
|
pw groupadd input
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Successfully created 'input' group."
|
||||||
|
else
|
||||||
|
echo "Warning: Failed to create 'input' group. You may need to create it manually."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "'input' group already exists."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set permissions on /dev/uinput if it exists
|
||||||
|
if [ -e /dev/uinput ]; then
|
||||||
|
echo "Setting permissions on /dev/uinput..."
|
||||||
|
chown root:input /dev/uinput
|
||||||
|
chmod 660 /dev/uinput
|
||||||
|
echo "Permissions set on /dev/uinput."
|
||||||
|
else
|
||||||
|
echo "Note: /dev/uinput does not exist. It will be created when needed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create devfs rules for persistent permissions
|
||||||
|
echo "Creating devfs rules for persistent permissions..."
|
||||||
|
DEVFS_RULESET_FILE="/etc/devfs.rules"
|
||||||
|
RULESET_NUM=47989
|
||||||
|
|
||||||
|
# Check if our rules already exist
|
||||||
|
if ! grep -q "\[sunshine=$RULESET_NUM\]" "$DEVFS_RULESET_FILE" 2>/dev/null; then
|
||||||
|
cat >> "$DEVFS_RULESET_FILE" << EOF
|
||||||
|
|
||||||
|
[sunshine=$RULESET_NUM]
|
||||||
|
add path 'uinput' mode 0660 group input
|
||||||
|
EOF
|
||||||
|
echo "Devfs rules added to $DEVFS_RULESET_FILE"
|
||||||
|
else
|
||||||
|
echo "Devfs rules already exist in $DEVFS_RULESET_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Apply the devfs ruleset immediately (without waiting for reboot)
|
||||||
|
echo "Applying devfs ruleset to current system..."
|
||||||
|
if [ -e /dev/uinput ]; then
|
||||||
|
devfs -m /dev rule -s $RULESET_NUM apply
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Post-installation configuration complete!"
|
||||||
|
echo ""
|
||||||
|
echo "IMPORTANT: To use virtual input devices (keyboard, mouse, gamepads),"
|
||||||
|
echo "you must add your user to the 'input' group:"
|
||||||
|
echo ""
|
||||||
|
echo " pw groupmod input -m \$USER"
|
||||||
|
echo ""
|
||||||
|
echo "After adding yourself to the group, log out and log back in for the"
|
||||||
|
echo "changes to take effect."
|
||||||
|
echo ""
|
||||||
32
src_assets/bsd/misc/+PRE_DEINSTALL
Normal file
32
src_assets/bsd/misc/+PRE_DEINSTALL
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# FreeBSD pre-deinstall script for Sunshine
|
||||||
|
# This script cleans up configuration added during installation
|
||||||
|
|
||||||
|
echo "Cleaning up Sunshine configuration..."
|
||||||
|
|
||||||
|
# Remove devfs rules
|
||||||
|
DEVFS_RULESET_FILE="/etc/devfs.rules"
|
||||||
|
RULESET_NUM=47989
|
||||||
|
|
||||||
|
# Remove rules from /etc/devfs.rules
|
||||||
|
if [ -f "$DEVFS_RULESET_FILE" ]; then
|
||||||
|
if grep -q "\[sunshine=$RULESET_NUM\]" "$DEVFS_RULESET_FILE"; then
|
||||||
|
echo "Removing devfs rules from $DEVFS_RULESET_FILE..."
|
||||||
|
# Remove the [sunshine=47989] section and its rules (match the section header and the next line)
|
||||||
|
sed -i.bak '/^\[sunshine='"$RULESET_NUM"'\]$/,/^add path.*uinput/d' "$DEVFS_RULESET_FILE"
|
||||||
|
echo "Devfs rules removed from file."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Removing devfs ruleset from memory..."
|
||||||
|
devfs rule -s $RULESET_NUM delset 2>/dev/null || true
|
||||||
|
|
||||||
|
# Note: We intentionally do NOT:
|
||||||
|
# - Remove the 'input' group (other software may use it)
|
||||||
|
|
||||||
|
echo "Cleanup complete."
|
||||||
|
echo ""
|
||||||
|
echo "NOTE: The 'input' group has not been removed as other software may use it."
|
||||||
|
echo "If you wish to remove it manually, run: pw groupdel input"
|
||||||
|
echo ""
|
||||||
|
|
@ -12,6 +12,10 @@ const props = defineProps({
|
||||||
<slot name="windows"></slot>
|
<slot name="windows"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template v-if="$slots.freebsd && platform === 'freebsd'">
|
||||||
|
<slot name="freebsd"></slot>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-if="$slots.linux && platform === 'linux'">
|
<template v-if="$slots.linux && platform === 'linux'">
|
||||||
<slot name="linux"></slot>
|
<slot name="linux"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,7 @@
|
||||||
<div class="form-text" v-if="platform === 'windows'"><b>{{ $t('apps.env_qres_example') }}</b>
|
<div class="form-text" v-if="platform === 'windows'"><b>{{ $t('apps.env_qres_example') }}</b>
|
||||||
<pre>cmd /C <{{ $t('apps.env_qres_path') }}>\QRes.exe /X:%SUNSHINE_CLIENT_WIDTH% /Y:%SUNSHINE_CLIENT_HEIGHT% /R:%SUNSHINE_CLIENT_FPS%</pre>
|
<pre>cmd /C <{{ $t('apps.env_qres_path') }}>\QRes.exe /X:%SUNSHINE_CLIENT_WIDTH% /Y:%SUNSHINE_CLIENT_HEIGHT% /R:%SUNSHINE_CLIENT_FPS%</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text" v-else-if="platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b>
|
<div class="form-text" v-else-if="platform === 'freebsd' || platform === 'linux'"><b>{{ $t('apps.env_xrandr_example') }}</b>
|
||||||
<pre>sh -c "xrandr --output HDMI-1 --mode \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}\" --rate ${SUNSHINE_CLIENT_FPS}"</pre>
|
<pre>sh -c "xrandr --output HDMI-1 --mode \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}\" --rate ${SUNSHINE_CLIENT_FPS}"</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text" v-else-if="platform === 'macos'"><b>{{ $t('apps.env_displayplacer_example') }}</b>
|
<div class="form-text" v-else-if="platform === 'macos'"><b>{{ $t('apps.env_displayplacer_example') }}</b>
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@
|
||||||
return el.id !== "vt" && el.id !== "vaapi";
|
return el.id !== "vt" && el.id !== "vaapi";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.platform === "linux") {
|
if (this.platform === "freebsd" || this.platform === "linux") {
|
||||||
this.tabs = this.tabs.filter((el) => {
|
this.tabs = this.tabs.filter((el) => {
|
||||||
return el.id !== "amd" && el.id !== "qsv" && el.id !== "vt";
|
return el.id !== "amd" && el.id !== "qsv" && el.id !== "vt";
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,10 @@ const config = ref(props.config)
|
||||||
<select id="capture" class="form-select" v-model="config.capture">
|
<select id="capture" class="form-select" v-model="config.capture">
|
||||||
<option value="">{{ $t('_common.autodetect') }}</option>
|
<option value="">{{ $t('_common.autodetect') }}</option>
|
||||||
<PlatformLayout :platform="platform">
|
<PlatformLayout :platform="platform">
|
||||||
|
<template #freebsd>
|
||||||
|
<option value="wlr">wlroots</option>
|
||||||
|
<option value="x11">X11</option>
|
||||||
|
</template>
|
||||||
<template #linux>
|
<template #linux>
|
||||||
<option value="nvfbc">NvFBC</option>
|
<option value="nvfbc">NvFBC</option>
|
||||||
<option value="wlr">wlroots</option>
|
<option value="wlr">wlroots</option>
|
||||||
|
|
@ -90,6 +94,9 @@ const config = ref(props.config)
|
||||||
<option value="quicksync">Intel QuickSync</option>
|
<option value="quicksync">Intel QuickSync</option>
|
||||||
<option value="amdvce">AMD AMF/VCE</option>
|
<option value="amdvce">AMD AMF/VCE</option>
|
||||||
</template>
|
</template>
|
||||||
|
<template #freebsd>
|
||||||
|
<option value="vaapi">VA-API</option>
|
||||||
|
</template>
|
||||||
<template #linux>
|
<template #linux>
|
||||||
<option value="nvenc">NVIDIA NVENC</option>
|
<option value="nvenc">NVIDIA NVENC</option>
|
||||||
<option value="vaapi">VA-API</option>
|
<option value="vaapi">VA-API</option>
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ const config = ref(props.config)
|
||||||
<template #windows>
|
<template #windows>
|
||||||
<pre>tools\audio-info.exe</pre>
|
<pre>tools\audio-info.exe</pre>
|
||||||
</template>
|
</template>
|
||||||
|
<template #freebsd>
|
||||||
|
<pre>pacmd list-sinks | grep "name:"</pre>
|
||||||
|
<pre>pactl info | grep Source</pre>
|
||||||
|
</template>
|
||||||
<template #linux>
|
<template #linux>
|
||||||
<pre>pacmd list-sinks | grep "name:"</pre>
|
<pre>pacmd list-sinks | grep "name:"</pre>
|
||||||
<pre>pactl info | grep Source</pre>
|
<pre>pactl info | grep Source</pre>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@ const config = ref(props.config)
|
||||||
<option value="auto">{{ $t('_common.auto') }}</option>
|
<option value="auto">{{ $t('_common.auto') }}</option>
|
||||||
|
|
||||||
<PlatformLayout :platform="platform">
|
<PlatformLayout :platform="platform">
|
||||||
|
<template #freebsd>
|
||||||
|
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
|
||||||
|
<option value="xone">{{ $t("config.gamepad_xone") }}</option>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #linux>
|
<template #linux>
|
||||||
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
|
<option value="ds5">{{ $t("config.gamepad_ds5") }}</option>
|
||||||
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
|
<option value="switch">{{ $t("config.gamepad_switch") }}</option>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,16 @@ const config = ref(props.config)
|
||||||
{{ $t('config.adapter_name_desc_windows') }}<br>
|
{{ $t('config.adapter_name_desc_windows') }}<br>
|
||||||
<pre>tools\dxgi-info.exe</pre>
|
<pre>tools\dxgi-info.exe</pre>
|
||||||
</template>
|
</template>
|
||||||
|
<template #freebsd>
|
||||||
|
{{ $t('config.adapter_name_desc_linux_1') }}<br>
|
||||||
|
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>
|
||||||
|
<pre>
|
||||||
|
vainfo --display drm --device /dev/dri/renderD129 | \
|
||||||
|
grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version"
|
||||||
|
</pre>
|
||||||
|
{{ $t('config.adapter_name_desc_linux_3') }}<br>
|
||||||
|
<i>VAProfileH264High : VAEntrypointEncSlice</i>
|
||||||
|
</template>
|
||||||
<template #linux>
|
<template #linux>
|
||||||
{{ $t('config.adapter_name_desc_linux_1') }}<br>
|
{{ $t('config.adapter_name_desc_linux_1') }}<br>
|
||||||
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>
|
<pre>ls /dev/dri/renderD* # {{ $t('config.adapter_name_desc_linux_2') }}</pre>
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,8 @@ function addRemappingEntry() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #freebsd>
|
||||||
|
</template>
|
||||||
<template #linux>
|
<template #linux>
|
||||||
</template>
|
</template>
|
||||||
<template #macos>
|
<template #macos>
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,16 @@ const outputNamePlaceholder = (props.platform === 'windows') ? '{de9bb7e2-186e-5
|
||||||
<b> }</b>
|
<b> }</b>
|
||||||
</pre>
|
</pre>
|
||||||
</template>
|
</template>
|
||||||
|
<template #freebsd>
|
||||||
|
<pre style="white-space: pre-line;">
|
||||||
|
Info: Detecting displays
|
||||||
|
Info: Detected display: DVI-D-0 (id: 0) connected: false
|
||||||
|
Info: Detected display: HDMI-0 (id: 1) connected: true
|
||||||
|
Info: Detected display: DP-0 (id: 2) connected: true
|
||||||
|
Info: Detected display: DP-1 (id: 3) connected: false
|
||||||
|
Info: Detected display: DVI-D-1 (id: 4) connected: false
|
||||||
|
</pre>
|
||||||
|
</template>
|
||||||
<template #linux>
|
<template #linux>
|
||||||
<pre style="white-space: pre-line;">
|
<pre style="white-space: pre-line;">
|
||||||
Info: Detecting displays
|
Info: Detecting displays
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,12 @@ namespace test_utils {
|
||||||
#define IS_MACOS false
|
#define IS_MACOS false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#define IS_FREEBSD true
|
||||||
|
#else
|
||||||
|
#define IS_FREEBSD false
|
||||||
|
#endif
|
||||||
|
|
||||||
struct PlatformTestSuite: testing::Test {
|
struct PlatformTestSuite: testing::Test {
|
||||||
static void SetUpTestSuite() {
|
static void SetUpTestSuite() {
|
||||||
ASSERT_FALSE(platf_deinit);
|
ASSERT_FALSE(platf_deinit);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ struct MouseHIDTest: PlatformTestSuite, testing::WithParamInterface<util::point_
|
||||||
// the alternative `platf::abs_mouse` method seem to work better during tests,
|
// the alternative `platf::abs_mouse` method seem to work better during tests,
|
||||||
// but I'm not sure about real work
|
// but I'm not sure about real work
|
||||||
GTEST_SKIP() << "TODO Windows";
|
GTEST_SKIP() << "TODO Windows";
|
||||||
#elif __linux__
|
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||||
// TODO: Inputtino waiting https://github.com/games-on-whales/inputtino/issues/6 is resolved.
|
// TODO: Inputtino waiting https://github.com/games-on-whales/inputtino/issues/6 is resolved.
|
||||||
GTEST_SKIP() << "TODO Inputtino";
|
GTEST_SKIP() << "TODO Inputtino";
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -88,7 +88,7 @@ TEST_P(MouseHIDTest, AbsMoveInputTest) {
|
||||||
65535,
|
65535,
|
||||||
65535
|
65535
|
||||||
};
|
};
|
||||||
#elif __linux__
|
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||||
platf::touch_port_t abs_port {
|
platf::touch_port_t abs_port {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
&video::amdvce,
|
&video::amdvce,
|
||||||
&video::quicksync,
|
&video::quicksync,
|
||||||
#endif
|
#endif
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
&video::vaapi,
|
&video::vaapi,
|
||||||
#endif
|
#endif
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue