mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Compare commits
266 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bcc8f6d0b8 | |||
| 90ca6ee3cd | |||
| b679185c87 | |||
| 6bbed12083 | |||
| f04851891e | |||
| f94d9ca3bd | |||
| f833dda3b9 | |||
| ceecb39bc5 | |||
| c957ca7230 | |||
| 5dfd2676c2 | |||
| d650f67ece | |||
| 760e82913a | |||
| e64a44a3e6 | |||
| be9cf00b05 | |||
| 52fdabeb2e | |||
| 846f4c003e | |||
| dc5f2ac577 | |||
| 663650cb61 | |||
| 45aecae221 | |||
| 3d3669ae3a | |||
| ac2aba0faf | |||
| d0ca944b9c | |||
| 3d7c631abd | |||
| abe78823b6 | |||
| 7e03b03cb7 | |||
| 27fe997dc3 | |||
| fe46159e40 | |||
| 031aa985f1 | |||
| 07c61f70d9 | |||
| 71b05d2594 | |||
| 98665d1b82 | |||
| da0eedf888 | |||
| 1133cb619b | |||
| a091d209cf | |||
| 47c658815b | |||
| b0d0c74073 | |||
| 9535b4d480 | |||
| c64cbf57d8 | |||
| d11235bbe2 | |||
| 3054c6618e | |||
| f34d51dddc | |||
| e05ac797cc | |||
| 187059deef | |||
| 5c9f184314 | |||
| 49725c2cc6 | |||
| eec9a26952 | |||
| 88d616e978 | |||
| 4fccad5d10 | |||
| ec18363f51 | |||
| b87a36785b | |||
| 1d7b212d8d | |||
| 4b6f2a9efa | |||
| bdaf303da4 | |||
| 3fb773eedd | |||
| e73647973d | |||
| d2b3a075b2 | |||
| f139148745 | |||
| e2ec2c695c | |||
| ba4ec47a8c | |||
| de5ef3842c | |||
| 1129ed9be4 | |||
| 0d4f1544c7 | |||
| e68a9476b5 | |||
| 17556c7a95 | |||
| eca9f626a5 | |||
| 7562e05123 | |||
| bf17f2b4b9 | |||
| 88e193e9fd | |||
| e474a47fad | |||
| c77fb71a69 | |||
| 48dd5976e1 | |||
| 093f7e438b | |||
| 0a0c1745b3 | |||
| 7b5dc58140 | |||
| 8681d2f74a | |||
| 2b20ed873c | |||
| ae3c15b7fd | |||
| 8dafd8f300 | |||
| c9a1765f29 | |||
| cc246ea239 | |||
| 0ae5fceb07 | |||
| 6dd18050be | |||
| 9eca6e0b48 | |||
| 4d58d1be66 | |||
| 6694388969 | |||
| f7058cd125 | |||
| 80033b656f | |||
| 1c719fa743 | |||
| a9f5722fd9 | |||
| 0952d7917f | |||
| a3f50f32bf | |||
| ab1bfffbd4 | |||
| 41d6187f11 | |||
| d4b175b146 | |||
| 8905962389 | |||
| d9d34ccbbb | |||
| d21048c165 | |||
| 8b0c32a35f | |||
| db269d29e8 | |||
| f9f628eae6 | |||
| 92e9fbf2eb | |||
| db6e4f4bfc | |||
| b662db452f | |||
| 0d2ccb5fe5 | |||
| d33b5d60b6 | |||
| ef5d12395b | |||
| e18c261054 | |||
| 8851821484 | |||
| 3489cc8fe8 | |||
| 28bc97b92b | |||
| dbc5a7961e | |||
| 5f43f63990 | |||
| b775fe7486 | |||
| 60eaa326a2 | |||
| 672d4ad543 | |||
| 96e9e61437 | |||
| dbc6f70f19 | |||
| dfc9bc265c | |||
| 2ce511c4d3 | |||
| 99415a3841 | |||
| 244625d26a | |||
| 840434e709 | |||
| 72afa9ef99 | |||
| 7400f14322 | |||
| 85654316c7 | |||
| 8ecd58dd14 | |||
| 65c7f68c31 | |||
| bf6d0f871a | |||
| 3cd7c6c916 | |||
| 3227e934de | |||
| b66a009046 | |||
| 6ef4f62d5b | |||
| c038024108 | |||
| df49a01827 | |||
| 924c670915 | |||
| be89dff12a | |||
| c1807a1108 | |||
| b569acbb5d | |||
| 6e571a3163 | |||
| 01e78e2179 | |||
| 1b219a9d5c | |||
| 0ac01003b2 | |||
| a36bdfabd0 | |||
| 570abb194a | |||
| 4e00f37be9 | |||
| 334afc9838 | |||
| 64f9e53a36 | |||
| b94c6ab8d5 | |||
| 38ea333644 | |||
| efbdaf7aaf | |||
| aee7b37fc8 | |||
| 664460cd34 | |||
| a66e1b2e6d | |||
| 8000574a82 | |||
| 2eae5a86d2 | |||
| 75da934815 | |||
| ac71ebcad9 | |||
| 383a6c8a05 | |||
| 8e79fde0d9 | |||
| 4f4622eab9 | |||
| a2327b7350 | |||
| b76ada7f30 | |||
| 59b568a6d0 | |||
| 3d6bd26e59 | |||
| 4e17688b7c | |||
| f34548621f | |||
| 7a2e071081 | |||
| de7b57d807 | |||
| 6de9d0c024 | |||
| 8f69533f30 | |||
| d463853aeb | |||
| 1047d1cf6e | |||
| 0bfa12c38c | |||
| c8e4962cfd | |||
| 171005b6a3 | |||
| 8526f4a021 | |||
| 3e5d129248 | |||
| 6e98db3bf3 | |||
| ff0236639a | |||
| 959bf769fb | |||
| 3ae7c4f788 | |||
| 143b3df771 | |||
| c0c59a890a | |||
| 3c5f69b874 | |||
| 36a452c852 | |||
| c66b32fc6f | |||
| bc129a65d9 | |||
| 1137e8d1c9 | |||
| 95a44d3a33 | |||
| b8b2fab499 | |||
| 7aceb1072a | |||
| 13723893ba | |||
| 6fd4720faf | |||
| 966b8452b7 | |||
| 8dc4f77f42 | |||
| ab0240e9b7 | |||
| 399f262692 | |||
| d1385804bb | |||
| 948a965c7a | |||
| a13935e232 | |||
| 46f920ae2a | |||
| e79b561f2a | |||
| 9018fda92e | |||
| 76b8b9a44b | |||
| 36a129f668 | |||
| 24e94acbb9 | |||
| 716f0a3bbb | |||
| f839fcfa29 | |||
| 41d930b1e1 | |||
| 5e615d12d5 | |||
| 17711ee5c8 | |||
| 9ff3142b61 | |||
| 8e5c2adda3 | |||
| 01d37653b0 | |||
| f5dbbb70ef | |||
| fc3f47742a | |||
| 1d2b6c0b1a | |||
| 5ebf984e9a | |||
| bfa59d2c04 | |||
| c1c59cff6d | |||
| 519dae9462 | |||
| 34419d9bcf | |||
| 532b3cd457 | |||
| 437006f5f1 | |||
| 1c858ae835 | |||
| 349fdd47e4 | |||
| c64854804d | |||
| f3e54f33c2 | |||
| 5f3ff07b4b | |||
| e8db71fe19 | |||
| 8984aa740e | |||
| c081268b7c | |||
| fae8d1dd10 | |||
| 217ea61568 | |||
| ba7885913d | |||
| a8afd05d19 | |||
| f4f1592bfa | |||
| cdc8124883 | |||
| c53191a441 | |||
| 14aadd5b61 | |||
| e38f094c16 | |||
| 452d52c217 | |||
| c585e09ef0 | |||
| 464e00d616 | |||
| b8e25bdc4e | |||
| 379c39d8b5 | |||
| f2a41b82bc | |||
| d1a98fe69f | |||
| ef3412f81b | |||
| 1812c30fbf | |||
| 3c45f2e590 | |||
| 735a464f68 | |||
| 3e3dfb4a02 | |||
| f77a9c185d | |||
| d3a5f986a8 | |||
| ef60910e51 | |||
| 565934ba2e | |||
| 5c5e12f0a7 | |||
| b3e7451a08 | |||
| da76dcb2fe | |||
| cbc8b1f11d | |||
| 5ca4268be2 | |||
| ff8bfadd25 | |||
| 1fc0f75776 | |||
| bf707c2e94 | |||
| 08cd4ac1ee |
+28
-77
@@ -35,7 +35,7 @@ jobs:
|
|||||||
run: uname -a
|
run: uname -a
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
|
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --target package --verbose -j4
|
run: cmake --build . --target package --verbose -j4
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
run: cat /proc/cpuinfo
|
run: cat /proc/cpuinfo
|
||||||
|
|
||||||
- name: install required packages
|
- name: install required packages
|
||||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev python3-requests
|
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev
|
||||||
|
|
||||||
- name: install linuxbrew packages
|
- name: install linuxbrew packages
|
||||||
run: |
|
run: |
|
||||||
@@ -93,7 +93,7 @@ jobs:
|
|||||||
languages: c
|
languages: c
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --target package --verbose -j4
|
run: cmake --build . --target package --verbose -j4
|
||||||
@@ -149,10 +149,10 @@ jobs:
|
|||||||
run: cat /proc/cpuinfo
|
run: cat /proc/cpuinfo
|
||||||
|
|
||||||
- name: install required packages
|
- name: install required packages
|
||||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev python3-requests libchafa-dev libddcutil-dev rpm
|
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev libchafa-dev libddcutil-dev rpm
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --target package --verbose -j4
|
run: cmake --build . --target package --verbose -j4
|
||||||
@@ -187,7 +187,7 @@ jobs:
|
|||||||
|
|
||||||
linux-armv7l:
|
linux-armv7l:
|
||||||
name: Linux-armv7l
|
name: Linux-armv7l
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
contents: read
|
contents: read
|
||||||
@@ -196,7 +196,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v2
|
uses: uraimo/run-on-arch-action@v3
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: armv7
|
arch: armv7
|
||||||
@@ -208,7 +208,7 @@ jobs:
|
|||||||
# CMake installed by apt has bug `list sub-command REMOVE_ITEM requires two or more arguments`
|
# CMake installed by apt has bug `list sub-command REMOVE_ITEM requires two or more arguments`
|
||||||
wget --no-check-certificate https://apt.kitware.com/ubuntu/pool/main/c/cmake/{cmake_3.29.2-0kitware1ubuntu20.04.1_armhf.deb,cmake-data_3.29.2-0kitware1ubuntu20.04.1_all.deb}
|
wget --no-check-certificate https://apt.kitware.com/ubuntu/pool/main/c/cmake/{cmake_3.29.2-0kitware1ubuntu20.04.1_armhf.deb,cmake-data_3.29.2-0kitware1ubuntu20.04.1_all.deb}
|
||||||
dpkg -i *.deb
|
dpkg -i *.deb
|
||||||
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
@@ -226,7 +226,7 @@ jobs:
|
|||||||
|
|
||||||
linux-armv6l:
|
linux-armv6l:
|
||||||
name: Linux-armv6l
|
name: Linux-armv6l
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
contents: read
|
contents: read
|
||||||
@@ -235,7 +235,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v2
|
uses: uraimo/run-on-arch-action@v3
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: armv6
|
arch: armv6
|
||||||
@@ -244,7 +244,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
apt-get update && apt-get install -y wget
|
apt-get update && apt-get install -y wget
|
||||||
apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
@@ -262,7 +262,7 @@ jobs:
|
|||||||
|
|
||||||
linux-riscv64:
|
linux-riscv64:
|
||||||
name: Linux-riscv64
|
name: Linux-riscv64
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
contents: read
|
contents: read
|
||||||
@@ -271,7 +271,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v2
|
uses: uraimo/run-on-arch-action@v3
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: riscv64
|
arch: riscv64
|
||||||
@@ -279,7 +279,7 @@ jobs:
|
|||||||
githubToken: ${{ github.token }}
|
githubToken: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
@@ -297,7 +297,7 @@ jobs:
|
|||||||
|
|
||||||
linux-ppc64le:
|
linux-ppc64le:
|
||||||
name: Linux-ppc64le
|
name: Linux-ppc64le
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
contents: read
|
contents: read
|
||||||
@@ -306,7 +306,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v2
|
uses: uraimo/run-on-arch-action@v3
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: ppc64le
|
arch: ppc64le
|
||||||
@@ -314,7 +314,7 @@ jobs:
|
|||||||
githubToken: ${{ github.token }}
|
githubToken: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
@@ -332,7 +332,7 @@ jobs:
|
|||||||
|
|
||||||
linux-s390x:
|
linux-s390x:
|
||||||
name: Linux-s390x
|
name: Linux-s390x
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
contents: read
|
contents: read
|
||||||
@@ -341,7 +341,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: uraimo/run-on-arch-action@v2
|
uses: uraimo/run-on-arch-action@v3
|
||||||
id: runcmd
|
id: runcmd
|
||||||
with:
|
with:
|
||||||
arch: s390x
|
arch: s390x
|
||||||
@@ -349,7 +349,7 @@ jobs:
|
|||||||
githubToken: ${{ github.token }}
|
githubToken: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
@@ -373,19 +373,17 @@ jobs:
|
|||||||
|
|
||||||
- name: setup alpine linux
|
- name: setup alpine linux
|
||||||
uses: jirutka/setup-alpine@master
|
uses: jirutka/setup-alpine@master
|
||||||
with:
|
|
||||||
branch: v3.19
|
|
||||||
|
|
||||||
- name: install dependencies
|
- name: install dependencies
|
||||||
run: |
|
run: |
|
||||||
cat /etc/alpine-release
|
cat /etc/alpine-release
|
||||||
uname -a
|
uname -a
|
||||||
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev py3-requests gcc g++
|
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
|
||||||
shell: alpine.sh --root {0}
|
shell: alpine.sh --root {0}
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
run: |
|
run: |
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -DENABLE_EMBEDDED_PCIIDS=On -GNinja .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -GNinja .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
shell: alpine.sh {0}
|
shell: alpine.sh {0}
|
||||||
|
|
||||||
@@ -422,20 +420,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
|
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v3
|
|
||||||
with:
|
|
||||||
languages: c
|
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
|
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --target package --verbose -j4
|
run: cmake --build . --target package --verbose -j4
|
||||||
|
|
||||||
- name: perform CodeQL analysis
|
|
||||||
uses: github/codeql-action/analyze@v3
|
|
||||||
|
|
||||||
- name: list features
|
- name: list features
|
||||||
run: ./fastfetch --list-features
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
@@ -514,8 +504,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
sudo pkg update
|
sudo pkg update
|
||||||
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py311-requests chafa
|
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl opencl ocl-icd v4l_compat chafa
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
@@ -530,41 +520,6 @@ jobs:
|
|||||||
name: fastfetch-freebsd-amd64
|
name: fastfetch-freebsd-amd64
|
||||||
path: ./fastfetch-*.*
|
path: ./fastfetch-*.*
|
||||||
|
|
||||||
dragonfly-amd64:
|
|
||||||
name: DragonFly-amd64
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
security-events: write
|
|
||||||
contents: read
|
|
||||||
steps:
|
|
||||||
- name: checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: run VM
|
|
||||||
uses: vmactions/dragonflybsd-vm@v1
|
|
||||||
with:
|
|
||||||
usesh: yes
|
|
||||||
prepare: |
|
|
||||||
uname -a
|
|
||||||
pkg update
|
|
||||||
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py39-requests chafa libelf
|
|
||||||
|
|
||||||
run: |
|
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
|
|
||||||
cmake --build . --target package --verbose -j4
|
|
||||||
./fastfetch --list-features
|
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
|
||||||
time ./flashfetch
|
|
||||||
ldd fastfetch
|
|
||||||
ctest --output-on-failure
|
|
||||||
|
|
||||||
- name: upload artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: fastfetch-dragonfly-amd64
|
|
||||||
path: ./fastfetch-*.*
|
|
||||||
|
|
||||||
openbsd-amd64:
|
openbsd-amd64:
|
||||||
name: OpenBSD-amd64
|
name: OpenBSD-amd64
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -585,8 +540,8 @@ jobs:
|
|||||||
version: '7.6'
|
version: '7.6'
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio hwdata py3-requests
|
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
@@ -621,8 +576,8 @@ jobs:
|
|||||||
version: '10.1'
|
version: '10.1'
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick pulseaudio opencl-headers ocl-icd py312-requests
|
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick opencl-headers ocl-icd
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||||
cmake --build . --target package --verbose -j4
|
cmake --build . --target package --verbose -j4
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||||
@@ -669,9 +624,6 @@ jobs:
|
|||||||
- name: copy necessary dlls
|
- name: copy necessary dlls
|
||||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||||
|
|
||||||
- name: download amd_ags
|
|
||||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x64.dll
|
|
||||||
|
|
||||||
- name: list features
|
- name: list features
|
||||||
run: ./fastfetch --list-features
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
@@ -719,7 +671,6 @@ jobs:
|
|||||||
- freebsd-amd64
|
- freebsd-amd64
|
||||||
- openbsd-amd64
|
- openbsd-amd64
|
||||||
- netbsd-amd64
|
- netbsd-amd64
|
||||||
- dragonfly-amd64
|
|
||||||
- sunos-amd64
|
- sunos-amd64
|
||||||
- windows-amd64
|
- windows-amd64
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
+131
-1
@@ -1,3 +1,133 @@
|
|||||||
|
# 2.40.1
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix compiling error on old intel platform (TPM, macOS)
|
||||||
|
* Fix `--file-raw -` no longer working (Logo, #1659)
|
||||||
|
* Regression of v2.40.0
|
||||||
|
|
||||||
|
# 2.40.0
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* In `key-format` of `LocalIP` module, `{name}` has been renamed to `{ifname}` for consistency (LocalIP, #1639)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Support Warp Terminal font detection (TerminalFont, Windows)
|
||||||
|
* Support more AMD GPU information using ADL SDK, including memory type detection (GPU, Windows)
|
||||||
|
* Support Intel dGPU memory type detection (GPU, Windows)
|
||||||
|
* Support Nvidia VMEM type detection via NVAPI (GPU, Windows, #993)
|
||||||
|
* Support Boot manager detection for OpenBSD and NetBSD (Bootmgr, OpenBSD / NetBSD)
|
||||||
|
* Use `SystemConfiguration` for DNS entries detection (DNS, macOS)
|
||||||
|
* Add `systemd-resolved` support for DNS module (DNS, Linux, #1646)
|
||||||
|
* Improve performance and accuracy of Wifi detection on FreeBSD using ioctl (Wifi, FreeBSD)
|
||||||
|
* Support remaining time reporting for batteries on NetBSD (Battery, NetBSD)
|
||||||
|
* Add new Mac models support (Host, macOS)
|
||||||
|
* Load config from fastfetch binary path with `--config` option (#1649)
|
||||||
|
* Support TPM detection on macOS (TPM, macOS)
|
||||||
|
* Support IPv6 client address report (Users, Linux / Windows)
|
||||||
|
* Support default route detection for IPv6 (LocalIP, Linux)
|
||||||
|
* Round seconds to the nearest minute to match the behavior of `uptime` command (Uptime)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix `outputColor` not working when `length` is set in Separator module (#1644)
|
||||||
|
* Fix CPU detection on PowerPC platforms (#1640, CPU, Linux)
|
||||||
|
* Fix battery manufacture date detection (Battery, macOS)
|
||||||
|
* Fix battery critical state detection (Battery, Linux)
|
||||||
|
* Fix Warp Terminal PID detection (Terminal, macOS)
|
||||||
|
* Remove disk creation time detection support on SunOS as ctim is file status change timestamp, not creation time (Disk, SunOS)
|
||||||
|
* Fall back to KDGKBINFO if `usbhid` fails (Keyboard, FreeBSD)
|
||||||
|
* Fix multiple paging file support (Swap, Windows)
|
||||||
|
* Fix memleaks, code smells in multiple modules
|
||||||
|
* Fix boot time calculation on NetBSD (Uptime, NetBSD)
|
||||||
|
* Temporarily fix Hyprland version detection (WM, Linux, #1657)
|
||||||
|
|
||||||
|
Logo:
|
||||||
|
* Fix opensuse-tumbleweed_small (#1636)
|
||||||
|
* Change WiiLinuxNgx to more generic name with aliases Wii-Linux and WiiLinux (#1633)
|
||||||
|
* Change name of Xray-OS to Ada (#1651)
|
||||||
|
* Change Nexa Linux logo (#1653)
|
||||||
|
|
||||||
|
# 2.39.1
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix a regression that PublicIP detection fails randomly (PublicIP, #1629)
|
||||||
|
|
||||||
|
# 2.39.0
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* OSMesa backend for OpenGL detection is removed (#1618)
|
||||||
|
* Fastfetch no longer tries to use the private framework `Apple80211` to acquire SSID for Wifi module, which is only useful for macOS Sonoma (Wifi, macOS)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Improve accuracy of HDR support on Windows 11 24H2 (Display, Windows)
|
||||||
|
* Improve performance of SSID detection on macOS Sequoia (Wifi, macOS, #1597)
|
||||||
|
* Support warp terminal version detection on Windows (Terminal, Windows)
|
||||||
|
* Support default route detection on OpenBSD & DragonFly BSD (LocalIP, OpenBSD / DragonFly)
|
||||||
|
* Improve bash completion script
|
||||||
|
* Improve performance of networking (PublicIP / Weather)
|
||||||
|
* Support pkgsrc package manager detection on Linux (Packages, Linux)
|
||||||
|
|
||||||
|
Logo:
|
||||||
|
* Add Common Torizon OS
|
||||||
|
* Change FoxOS to WolfOS
|
||||||
|
* Add Bredos
|
||||||
|
* Add NetBSD2
|
||||||
|
|
||||||
|
# 2.38.0
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix empty battery slots handling (Battery, Haiku, #1575)
|
||||||
|
* Fix `{day-pretty}` output in custom format (DateTime, Windows)
|
||||||
|
* Fix VanillaOS detection (OS, Linux)
|
||||||
|
* Fix secure boot testing (Bootmgr, Linux, #1584)
|
||||||
|
* Fix the SI unit "kB" in help message (#1589)
|
||||||
|
* Fix segfault on macOS 10.15 when using the binary downloaded from Github Releases (Camera, macOS, #1594)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Support Chassis module in macOS (Chassis, macOS)
|
||||||
|
* Allow customize key format with kernel name and distro name (OS)
|
||||||
|
* Add missing `{icon}` in custom key format (Battery)
|
||||||
|
* Add missing `{mountpoint}` and `{mount-from}` in custom output format (Disk, #1577)
|
||||||
|
* Support percentage num & bar in custom format (GPU, #1583)
|
||||||
|
* Support `pisi` package manager detection (Packages, Linux)
|
||||||
|
* Support termite terminal font detection (TerminalFont, Linux)
|
||||||
|
* Report monitor type in Brightness module (Brightness)
|
||||||
|
|
||||||
|
Logo:
|
||||||
|
* Add `opensuse-tumbleweed_small`
|
||||||
|
* Add `Bedrock_small`
|
||||||
|
* Add `fastfetch`
|
||||||
|
* Remove some unnecessary distro names
|
||||||
|
|
||||||
|
# 2.37.0
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* Option `--escape-bedrock` is removed. The function is always enabled now.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Support for Haiku is greatly improved (Haiku)
|
||||||
|
* CPU, GPU, Disk, Sound, Terminal, Terminal Font, Init System, Battery, Mouse, Keyboard, NetIO, CPU Usage, Physical Disk and OpenGL should work on Haiku now
|
||||||
|
* SMBIOS related modules (Host, Bios, Board, Chassis, Physical Memory) should work in platforms with legacy BIOS system.
|
||||||
|
* Support for Gamepad and Bluetooth are WIP.
|
||||||
|
* Some bugs are found and fixed.
|
||||||
|
* Remove `python-requests` dependency in `scripts/gen-*.py`.
|
||||||
|
* Add cmake option `-DENABLE_EMBEDDED_AMDGPUIDS=BOOL` (disabled by default)
|
||||||
|
* If enabled, fastfetch will embed the newest [`amdgpu.ids`](https://gitlab.freedesktop.org/mesa/drm/-/blob/main/data/amdgpu.ids?ref_type=heads) file into fastfetch binary.
|
||||||
|
* Weather module now honors `display.temp.unit` option (#1560, Weather)
|
||||||
|
* Support Physical Memory module in NetBSD (PhysicalMemory, NetBSD)
|
||||||
|
* Requires root permission
|
||||||
|
* Improve non-intel CPU detection in NetBSD (#1573, CPU, NetBSD)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix building in macOS 10.13 (GPU, macOS)
|
||||||
|
* Properly round percent values when detecting volume (#1558, Sound)
|
||||||
|
* Fix Physical Memory module doesn't work in `--format json` mode
|
||||||
|
* Add some missing variable inits (GPU, Linux)
|
||||||
|
* Fix `--localip-default-route-only false` not working with `--gen-config` (#1570, LocalIP)
|
||||||
|
|
||||||
|
Logo:
|
||||||
|
* Update Rosa linux
|
||||||
|
* Add Haiku2
|
||||||
|
|
||||||
# 2.36.1
|
# 2.36.1
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
@@ -254,7 +384,7 @@ Features:
|
|||||||
* Support tilix version detection (Terminal, Linux)
|
* Support tilix version detection (Terminal, Linux)
|
||||||
* Support percent type config in module level. Example:
|
* Support percent type config in module level. Example:
|
||||||
|
|
||||||
```json
|
```jsonc
|
||||||
{
|
{
|
||||||
"type": "memory",
|
"type": "memory",
|
||||||
"percent": {
|
"percent": {
|
||||||
|
|||||||
+92
-58
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||||
|
|
||||||
project(fastfetch
|
project(fastfetch
|
||||||
VERSION 2.36.1
|
VERSION 2.40.1
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
DESCRIPTION "Fast neofetch-like system information tool"
|
DESCRIPTION "Fast neofetch-like system information tool"
|
||||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||||
@@ -56,7 +56,7 @@ include(CheckIncludeFile)
|
|||||||
|
|
||||||
include(CMakeDependentOption)
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku" OFF)
|
||||||
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD" OFF)
|
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD" OFF)
|
||||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||||
@@ -64,23 +64,22 @@ cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBS
|
|||||||
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX" OFF)
|
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX" OFF)
|
||||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR Haiku" OFF)
|
||||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
|
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
|
||||||
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR WIN32 OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR WIN32 OR SunOS OR Haiku" OFF)
|
||||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||||
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku" OFF)
|
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku" OFF)
|
||||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku" OFF)
|
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku" OFF)
|
||||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
|
||||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly" OFF)
|
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly OR Haiku" OFF)
|
||||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||||
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
||||||
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD OR SunOS" OFF)
|
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD OR SunOS" OFF)
|
||||||
@@ -94,6 +93,7 @@ option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by gith
|
|||||||
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
|
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
|
||||||
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
|
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
|
||||||
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
|
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
|
||||||
|
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
|
||||||
|
|
||||||
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
|
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
|
||||||
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
|
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
|
||||||
@@ -102,7 +102,7 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
|
|||||||
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
|
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
|
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
|
||||||
foreach(package_manager ${PACKAGE_MANAGERS})
|
foreach(package_manager ${PACKAGE_MANAGERS})
|
||||||
if(package_manager STREQUAL "WINGET")
|
if(package_manager STREQUAL "WINGET")
|
||||||
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
|
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
|
||||||
@@ -271,11 +271,16 @@ endif()
|
|||||||
|
|
||||||
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc")
|
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc")
|
||||||
if(Python_FOUND)
|
if(Python_FOUND)
|
||||||
|
if(NOT EXISTS "${PROJECT_BINARY_DIR}/pci.ids")
|
||||||
|
message(STATUS "'${PROJECT_BINARY_DIR}/pci.ids' is missing, downloading...")
|
||||||
|
file(DOWNLOAD "https://pci-ids.ucw.cz/v2.2/pci.ids" "${PROJECT_BINARY_DIR}/pci.ids")
|
||||||
|
endif()
|
||||||
message(STATUS "Generating 'fastfetch_pciids.c.inc'")
|
message(STATUS "Generating 'fastfetch_pciids.c.inc'")
|
||||||
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py"
|
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py" "${PROJECT_BINARY_DIR}/pci.ids"
|
||||||
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc"
|
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc"
|
||||||
RESULT_VARIABLE PYTHON_PCIIDS_RETCODE)
|
RESULT_VARIABLE PYTHON_PCIIDS_RETCODE)
|
||||||
if(NOT PYTHON_PCIIDS_RETCODE EQUAL 0)
|
if(NOT PYTHON_PCIIDS_RETCODE EQUAL 0)
|
||||||
|
file(REMOVE "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc")
|
||||||
message(FATAL_ERROR "Failed to generate 'fastfetch_pciids.c.inc'")
|
message(FATAL_ERROR "Failed to generate 'fastfetch_pciids.c.inc'")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
@@ -284,6 +289,26 @@ if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_EMBEDDED_AMDGPUIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_amdgpuids.c.inc")
|
||||||
|
if(Python_FOUND)
|
||||||
|
if(NOT EXISTS "${PROJECT_BINARY_DIR}/amdgpu.ids")
|
||||||
|
message(STATUS "'${PROJECT_BINARY_DIR}/amdgpu.ids' is missing, downloading...")
|
||||||
|
file(DOWNLOAD "https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids" "${PROJECT_BINARY_DIR}/amdgpu.ids")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Generating 'fastfetch_amdgpuids.c.inc'")
|
||||||
|
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-amdgpuids.py" "${PROJECT_BINARY_DIR}/amdgpu.ids"
|
||||||
|
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch_amdgpuids.c.inc"
|
||||||
|
RESULT_VARIABLE PYTHON_AMDGPUIDS_RETCODE)
|
||||||
|
if(NOT PYTHON_AMDGPUIDS_RETCODE EQUAL 0)
|
||||||
|
file(REMOVE "${PROJECT_BINARY_DIR}/fastfetch_amdgpuids.c.inc")
|
||||||
|
message(FATAL_ERROR "Failed to generate 'fastfetch_amdgpuids.c.inc'")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "Python3 is not found, 'fastfetch_amdgpuids.c.inc' will not be generated")
|
||||||
|
set(ENABLE_EMBEDDED_AMDGPUIDS OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(Python_FOUND)
|
if(Python_FOUND)
|
||||||
message(STATUS "Generating 'fastfetch.1'")
|
message(STATUS "Generating 'fastfetch.1'")
|
||||||
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-man.py"
|
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-man.py"
|
||||||
@@ -339,6 +364,7 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/common/library.c
|
src/common/library.c
|
||||||
src/common/modules.c
|
src/common/modules.c
|
||||||
src/common/netif/netif.c
|
src/common/netif/netif.c
|
||||||
|
src/common/networking/networking_common.c
|
||||||
src/common/option.c
|
src/common/option.c
|
||||||
src/common/parsing.c
|
src/common/parsing.c
|
||||||
src/common/printing.c
|
src/common/printing.c
|
||||||
@@ -467,7 +493,7 @@ if(LINUX)
|
|||||||
src/common/dbus.c
|
src/common/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_linux.c
|
src/common/netif/netif_linux.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/detection/battery/battery_linux.c
|
src/detection/battery/battery_linux.c
|
||||||
src/detection/bios/bios_linux.c
|
src/detection/bios/bios_linux.c
|
||||||
@@ -548,7 +574,7 @@ elseif(ANDROID)
|
|||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_linux.c
|
src/common/netif/netif_linux.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/detection/battery/battery_android.c
|
src/detection/battery/battery_android.c
|
||||||
src/detection/bios/bios_android.c
|
src/detection/bios/bios_android.c
|
||||||
@@ -614,7 +640,7 @@ elseif(FreeBSD)
|
|||||||
src/common/dbus.c
|
src/common/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/netif/netif_bsd.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/sysctl.c
|
||||||
src/detection/battery/battery_bsd.c
|
src/detection/battery/battery_bsd.c
|
||||||
@@ -682,7 +708,6 @@ elseif(FreeBSD)
|
|||||||
src/detection/uptime/uptime_bsd.c
|
src/detection/uptime/uptime_bsd.c
|
||||||
src/detection/users/users_linux.c
|
src/detection/users/users_linux.c
|
||||||
src/detection/wallpaper/wallpaper_linux.c
|
src/detection/wallpaper/wallpaper_linux.c
|
||||||
src/detection/wifi/wifi_bsd.c
|
|
||||||
src/detection/wm/wm_nosupport.c
|
src/detection/wm/wm_nosupport.c
|
||||||
src/detection/de/de_linux.c
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
@@ -694,10 +719,12 @@ elseif(FreeBSD)
|
|||||||
if(DragonFly)
|
if(DragonFly)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/detection/bluetooth/bluetooth_nosupport.c
|
src/detection/bluetooth/bluetooth_nosupport.c
|
||||||
|
src/detection/wifi/wifi_nosupport.c
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/detection/bluetooth/bluetooth_bsd.c
|
src/detection/bluetooth/bluetooth_bsd.c
|
||||||
|
src/detection/wifi/wifi_bsd.c
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
elseif(NetBSD)
|
elseif(NetBSD)
|
||||||
@@ -705,7 +732,7 @@ elseif(NetBSD)
|
|||||||
src/common/dbus.c
|
src/common/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/netif/netif_bsd.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/sysctl.c
|
||||||
src/detection/battery/battery_nbsd.c
|
src/detection/battery/battery_nbsd.c
|
||||||
@@ -713,18 +740,18 @@ elseif(NetBSD)
|
|||||||
src/detection/bluetooth/bluetooth_nosupport.c
|
src/detection/bluetooth/bluetooth_nosupport.c
|
||||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||||
src/detection/board/board_nbsd.c
|
src/detection/board/board_nbsd.c
|
||||||
src/detection/bootmgr/bootmgr_nosupport.c
|
src/detection/bootmgr/bootmgr_bsd.c
|
||||||
src/detection/brightness/brightness_nbsd.c
|
src/detection/brightness/brightness_nbsd.c
|
||||||
src/detection/btrfs/btrfs_nosupport.c
|
src/detection/btrfs/btrfs_nosupport.c
|
||||||
src/detection/chassis/chassis_nbsd.c
|
src/detection/chassis/chassis_nbsd.c
|
||||||
src/detection/cpu/cpu_nbsd.c
|
src/detection/cpu/cpu_nbsd.c
|
||||||
src/detection/cpucache/cpucache_nosupport.c
|
src/detection/cpucache/cpucache_shared.c
|
||||||
src/detection/cpuusage/cpuusage_bsd.c
|
src/detection/cpuusage/cpuusage_bsd.c
|
||||||
src/detection/cursor/cursor_linux.c
|
src/detection/cursor/cursor_linux.c
|
||||||
src/detection/disk/disk_bsd.c
|
src/detection/disk/disk_bsd.c
|
||||||
src/detection/dns/dns_linux.c
|
src/detection/dns/dns_linux.c
|
||||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
src/detection/physicaldisk/physicaldisk_nosupport.c
|
||||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
src/detection/physicalmemory/physicalmemory_linux.c
|
||||||
src/detection/diskio/diskio_nbsd.c
|
src/detection/diskio/diskio_nbsd.c
|
||||||
src/detection/displayserver/linux/displayserver_linux.c
|
src/detection/displayserver/linux/displayserver_linux.c
|
||||||
src/detection/displayserver/linux/drm.c
|
src/detection/displayserver/linux/drm.c
|
||||||
@@ -787,26 +814,26 @@ elseif(OpenBSD)
|
|||||||
src/common/dbus.c
|
src/common/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/netif/netif_bsd.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/sysctl.c
|
||||||
src/detection/battery/battery_obsd.c
|
src/detection/battery/battery_obsd.c
|
||||||
src/detection/bios/bios_nosupport.c
|
src/detection/bios/bios_windows.c
|
||||||
src/detection/bluetooth/bluetooth_nosupport.c
|
src/detection/bluetooth/bluetooth_nosupport.c
|
||||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||||
src/detection/board/board_nosupport.c
|
src/detection/board/board_windows.c
|
||||||
src/detection/bootmgr/bootmgr_nosupport.c
|
src/detection/bootmgr/bootmgr_bsd.c
|
||||||
src/detection/brightness/brightness_obsd.c
|
src/detection/brightness/brightness_obsd.c
|
||||||
src/detection/btrfs/btrfs_nosupport.c
|
src/detection/btrfs/btrfs_nosupport.c
|
||||||
src/detection/chassis/chassis_nosupport.c
|
src/detection/chassis/chassis_windows.c
|
||||||
src/detection/cpu/cpu_obsd.c
|
src/detection/cpu/cpu_obsd.c
|
||||||
src/detection/cpucache/cpucache_nosupport.c
|
src/detection/cpucache/cpucache_shared.c
|
||||||
src/detection/cpuusage/cpuusage_bsd.c
|
src/detection/cpuusage/cpuusage_bsd.c
|
||||||
src/detection/cursor/cursor_linux.c
|
src/detection/cursor/cursor_linux.c
|
||||||
src/detection/disk/disk_bsd.c
|
src/detection/disk/disk_bsd.c
|
||||||
src/detection/dns/dns_linux.c
|
src/detection/dns/dns_linux.c
|
||||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
src/detection/physicaldisk/physicaldisk_nosupport.c
|
||||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
src/detection/physicalmemory/physicalmemory_linux.c
|
||||||
src/detection/diskio/diskio_obsd.c
|
src/detection/diskio/diskio_obsd.c
|
||||||
src/detection/displayserver/linux/displayserver_linux.c
|
src/detection/displayserver/linux/displayserver_linux.c
|
||||||
src/detection/displayserver/linux/drm.c
|
src/detection/displayserver/linux/drm.c
|
||||||
@@ -863,12 +890,13 @@ elseif(OpenBSD)
|
|||||||
src/detection/zpool/zpool_nosupport.c
|
src/detection/zpool/zpool_nosupport.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
src/util/platform/FFPlatform_unix.c
|
||||||
src/util/binary_linux.c
|
src/util/binary_linux.c
|
||||||
|
src/util/smbiosHelper.c
|
||||||
)
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/netif/netif_bsd.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/common/sysctl.c
|
src/common/sysctl.c
|
||||||
src/detection/battery/battery_apple.c
|
src/detection/battery/battery_apple.c
|
||||||
@@ -879,13 +907,13 @@ elseif(APPLE)
|
|||||||
src/detection/bootmgr/bootmgr_apple.c
|
src/detection/bootmgr/bootmgr_apple.c
|
||||||
src/detection/brightness/brightness_apple.c
|
src/detection/brightness/brightness_apple.c
|
||||||
src/detection/btrfs/btrfs_nosupport.c
|
src/detection/btrfs/btrfs_nosupport.c
|
||||||
src/detection/chassis/chassis_nosupport.c
|
src/detection/chassis/chassis_apple.c
|
||||||
src/detection/cpu/cpu_apple.c
|
src/detection/cpu/cpu_apple.c
|
||||||
src/detection/cpucache/cpucache_apple.c
|
src/detection/cpucache/cpucache_apple.c
|
||||||
src/detection/cpuusage/cpuusage_apple.c
|
src/detection/cpuusage/cpuusage_apple.c
|
||||||
src/detection/cursor/cursor_apple.m
|
src/detection/cursor/cursor_apple.m
|
||||||
src/detection/disk/disk_bsd.c
|
src/detection/disk/disk_bsd.c
|
||||||
src/detection/dns/dns_linux.c
|
src/detection/dns/dns_apple.c
|
||||||
src/detection/physicaldisk/physicaldisk_apple.c
|
src/detection/physicaldisk/physicaldisk_apple.c
|
||||||
src/detection/physicalmemory/physicalmemory_apple.m
|
src/detection/physicalmemory/physicalmemory_apple.m
|
||||||
src/detection/diskio/diskio_apple.c
|
src/detection/diskio/diskio_apple.c
|
||||||
@@ -919,7 +947,7 @@ elseif(APPLE)
|
|||||||
src/detection/terminalshell/terminalshell_linux.c
|
src/detection/terminalshell/terminalshell_linux.c
|
||||||
src/detection/terminalsize/terminalsize_linux.c
|
src/detection/terminalsize/terminalsize_linux.c
|
||||||
src/detection/theme/theme_nosupport.c
|
src/detection/theme/theme_nosupport.c
|
||||||
src/detection/tpm/tpm_nosupport.c
|
src/detection/tpm/tpm_apple.c
|
||||||
src/detection/uptime/uptime_bsd.c
|
src/detection/uptime/uptime_bsd.c
|
||||||
src/detection/users/users_linux.c
|
src/detection/users/users_linux.c
|
||||||
src/detection/wallpaper/wallpaper_apple.m
|
src/detection/wallpaper/wallpaper_apple.m
|
||||||
@@ -939,7 +967,7 @@ elseif(WIN32)
|
|||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/io/io_windows.c
|
src/common/io/io_windows.c
|
||||||
src/common/netif/netif_windows.c
|
src/common/netif/netif_windows.c
|
||||||
src/common/networking_windows.c
|
src/common/networking/networking_windows.c
|
||||||
src/common/processing_windows.c
|
src/common/processing_windows.c
|
||||||
src/detection/battery/battery_windows.c
|
src/detection/battery/battery_windows.c
|
||||||
src/detection/bios/bios_windows.c
|
src/detection/bios/bios_windows.c
|
||||||
@@ -1008,13 +1036,14 @@ elseif(WIN32)
|
|||||||
src/util/windows/version.c
|
src/util/windows/version.c
|
||||||
src/util/platform/FFPlatform_windows.c
|
src/util/platform/FFPlatform_windows.c
|
||||||
src/util/binary_windows.c
|
src/util/binary_windows.c
|
||||||
|
src/util/debug_windows.c
|
||||||
)
|
)
|
||||||
elseif(SunOS)
|
elseif(SunOS)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
src/common/dbus.c
|
src/common/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_bsd.c
|
src/common/netif/netif_bsd.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/detection/battery/battery_nosupport.c
|
src/detection/battery/battery_nosupport.c
|
||||||
src/detection/bios/bios_windows.c
|
src/detection/bios/bios_windows.c
|
||||||
@@ -1092,54 +1121,55 @@ elseif(SunOS)
|
|||||||
)
|
)
|
||||||
elseif(Haiku)
|
elseif(Haiku)
|
||||||
list(APPEND LIBFASTFETCH_SRC
|
list(APPEND LIBFASTFETCH_SRC
|
||||||
|
src/common/dbus.c
|
||||||
src/common/io/io_unix.c
|
src/common/io/io_unix.c
|
||||||
src/common/netif/netif_haiku.c
|
src/common/netif/netif_haiku.c
|
||||||
src/common/networking_linux.c
|
src/common/networking/networking_linux.c
|
||||||
src/common/processing_linux.c
|
src/common/processing_linux.c
|
||||||
src/detection/battery/battery_nosupport.c
|
src/detection/battery/battery_haiku.c
|
||||||
src/detection/bios/bios_nosupport.c
|
src/detection/bios/bios_windows.c
|
||||||
src/detection/board/board_nosupport.c
|
src/detection/board/board_windows.c
|
||||||
src/detection/bootmgr/bootmgr_nosupport.c
|
src/detection/bootmgr/bootmgr_nosupport.c
|
||||||
src/detection/brightness/brightness_nosupport.c
|
src/detection/brightness/brightness_nosupport.c
|
||||||
src/detection/btrfs/btrfs_nosupport.c
|
src/detection/btrfs/btrfs_nosupport.c
|
||||||
src/detection/chassis/chassis_nosupport.c
|
src/detection/chassis/chassis_windows.c
|
||||||
src/detection/cpu/cpu_nosupport.c
|
src/detection/cpu/cpu_haiku.c
|
||||||
src/detection/cpucache/cpucache_nosupport.c
|
src/detection/cpucache/cpucache_shared.c
|
||||||
src/detection/cpuusage/cpuusage_nosupport.c
|
src/detection/cpuusage/cpuusage_haiku.c
|
||||||
src/detection/cursor/cursor_nosupport.c
|
src/detection/cursor/cursor_nosupport.c
|
||||||
src/detection/bluetooth/bluetooth_nosupport.c
|
src/detection/bluetooth/bluetooth_haiku.cpp
|
||||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||||
src/detection/disk/disk_nosupport.c
|
src/detection/disk/disk_haiku.cpp
|
||||||
src/detection/dns/dns_linux.c
|
src/detection/dns/dns_linux.c
|
||||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
src/detection/physicaldisk/physicaldisk_haiku.c
|
||||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
src/detection/physicalmemory/physicalmemory_linux.c
|
||||||
src/detection/diskio/diskio_nosupport.c
|
src/detection/diskio/diskio_nosupport.c
|
||||||
src/detection/displayserver/displayserver_haiku.cpp
|
src/detection/displayserver/displayserver_haiku.cpp
|
||||||
src/detection/font/font_haiku.cpp
|
src/detection/font/font_haiku.cpp
|
||||||
src/detection/gpu/gpu_nosupport.c
|
src/detection/gpu/gpu_haiku.c
|
||||||
src/detection/gpu/gpu_pci.c
|
src/detection/gpu/gpu_pci.c
|
||||||
src/detection/gtk_qt/gtk.c
|
src/detection/gtk_qt/gtk.c
|
||||||
src/detection/host/host_nosupport.c
|
src/detection/host/host_windows.c
|
||||||
src/detection/icons/icons_nosupport.c
|
src/detection/icons/icons_nosupport.c
|
||||||
src/detection/initsystem/initsystem_nosupport.c
|
src/detection/initsystem/initsystem_haiku.c
|
||||||
src/detection/keyboard/keyboard_nosupport.c
|
src/detection/keyboard/keyboard_haiku.cpp
|
||||||
src/detection/libc/libc_nosupport.c
|
src/detection/libc/libc_nosupport.c
|
||||||
src/detection/lm/lm_nosupport.c
|
src/detection/lm/lm_nosupport.c
|
||||||
src/detection/loadavg/loadavg_nosupport.c
|
src/detection/loadavg/loadavg_nosupport.c
|
||||||
src/detection/locale/locale_linux.c
|
src/detection/locale/locale_linux.c
|
||||||
src/detection/localip/localip_linux.c
|
src/detection/localip/localip_linux.c
|
||||||
src/detection/gamepad/gamepad_nosupport.c
|
src/detection/gamepad/gamepad_haiku.cpp
|
||||||
src/detection/media/media_nosupport.c
|
src/detection/media/media_linux.c
|
||||||
src/detection/memory/memory_haiku.c
|
src/detection/memory/memory_haiku.c
|
||||||
src/detection/mouse/mouse_nosupport.c
|
src/detection/mouse/mouse_haiku.cpp
|
||||||
src/detection/netio/netio_nosupport.c
|
src/detection/netio/netio_haiku.cpp
|
||||||
src/detection/opengl/opengl_linux.c
|
src/detection/opengl/opengl_haiku.cpp
|
||||||
src/detection/os/os_haiku.c
|
src/detection/os/os_haiku.c
|
||||||
src/detection/packages/packages_haiku.c
|
src/detection/packages/packages_haiku.c
|
||||||
src/detection/poweradapter/poweradapter_nosupport.c
|
src/detection/poweradapter/poweradapter_nosupport.c
|
||||||
src/detection/processes/processes_haiku.c
|
src/detection/processes/processes_haiku.c
|
||||||
src/detection/gtk_qt/qt.c
|
src/detection/gtk_qt/qt.c
|
||||||
src/detection/sound/sound_nosupport.c
|
src/detection/sound/sound_haiku.cpp
|
||||||
src/detection/swap/swap_haiku.c
|
src/detection/swap/swap_haiku.c
|
||||||
src/detection/terminalfont/terminalfont_linux.c
|
src/detection/terminalfont/terminalfont_linux.c
|
||||||
src/detection/terminalshell/terminalshell_linux.c
|
src/detection/terminalshell/terminalshell_linux.c
|
||||||
@@ -1157,6 +1187,7 @@ elseif(Haiku)
|
|||||||
src/detection/zpool/zpool_nosupport.c
|
src/detection/zpool/zpool_nosupport.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
src/util/platform/FFPlatform_unix.c
|
||||||
src/util/binary_linux.c
|
src/util/binary_linux.c
|
||||||
|
src/util/haiku/version.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -1450,10 +1481,6 @@ else()
|
|||||||
"GL"
|
"GL"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
ff_lib_enable(OSMESA
|
|
||||||
"osmesa"
|
|
||||||
"OSMesa"
|
|
||||||
)
|
|
||||||
ff_lib_enable(OPENCL
|
ff_lib_enable(OPENCL
|
||||||
"OpenCL"
|
"OpenCL"
|
||||||
"OpenCL"
|
"OpenCL"
|
||||||
@@ -1511,6 +1538,9 @@ endif()
|
|||||||
if(ENABLE_EMBEDDED_PCIIDS)
|
if(ENABLE_EMBEDDED_PCIIDS)
|
||||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_PCIIDS=1)
|
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_PCIIDS=1)
|
||||||
endif()
|
endif()
|
||||||
|
if(ENABLE_EMBEDDED_AMDGPUIDS)
|
||||||
|
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_AMDGPUIDS=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(LINUX)
|
if(LINUX)
|
||||||
target_link_libraries(libfastfetch
|
target_link_libraries(libfastfetch
|
||||||
@@ -1544,7 +1574,6 @@ elseif(APPLE)
|
|||||||
PRIVATE "-F /System/Library/PrivateFrameworks"
|
PRIVATE "-F /System/Library/PrivateFrameworks"
|
||||||
PRIVATE "-weak_framework DisplayServices"
|
PRIVATE "-weak_framework DisplayServices"
|
||||||
PRIVATE "-weak_framework MediaRemote"
|
PRIVATE "-weak_framework MediaRemote"
|
||||||
PRIVATE "-weak_framework Apple80211"
|
|
||||||
)
|
)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
target_link_libraries(libfastfetch
|
target_link_libraries(libfastfetch
|
||||||
@@ -1616,6 +1645,11 @@ elseif(ANDROID)
|
|||||||
elseif(Haiku)
|
elseif(Haiku)
|
||||||
target_link_libraries(libfastfetch
|
target_link_libraries(libfastfetch
|
||||||
PRIVATE "network"
|
PRIVATE "network"
|
||||||
|
PRIVATE "bnetapi"
|
||||||
|
PRIVATE "media"
|
||||||
|
PRIVATE "device"
|
||||||
|
PRIVATE "bluetooth"
|
||||||
|
PRIVATE "GL"
|
||||||
PRIVATE "be"
|
PRIVATE "be"
|
||||||
PRIVATE "gnu"
|
PRIVATE "gnu"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
[](https://repology.org/project/fastfetch/versions)
|
[](https://repology.org/project/fastfetch/versions)
|
||||||
[](https://repology.org/project/fastfetch/versions)
|
[](https://repology.org/project/fastfetch/versions)
|
||||||
|
|
||||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS and Windows 7+ are supported.
|
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. Currently, Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku and SunOS are supported.
|
||||||
|
|
||||||
<img src="screenshots/example1.png" width="49%" align="left" />
|
<img src="screenshots/example1.png" width="49%" align="left" />
|
||||||
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
||||||
@@ -29,6 +29,10 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
|
|||||||
|
|
||||||
Some distros package an outdated fastfetch version. Older versions receive no support, so please try always to use the latest version.
|
Some distros package an outdated fastfetch version. Older versions receive no support, so please try always to use the latest version.
|
||||||
|
|
||||||
|
<a href="https://repology.org/project/fastfetch/versions">
|
||||||
|
<img src="https://repology.org/badge/vertical-allrepos/fastfetch.svg?columns=2" alt="Packaging status" align="right">
|
||||||
|
</a>
|
||||||
|
|
||||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||||
* Debian: `apt install fastfetch` (for Debian 13 or newer)
|
* Debian: `apt install fastfetch` (for Debian 13 or newer)
|
||||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||||
@@ -47,8 +51,6 @@ Some distros package an outdated fastfetch version. Older versions receive no su
|
|||||||
|
|
||||||
You may need `sudo`, `doas` or `sup` to run these commands.
|
You may need `sudo`, `doas` or `sup` to run these commands.
|
||||||
|
|
||||||
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging).
|
|
||||||
|
|
||||||
If fastfetch is not packaged for your distro or an outdated version is packaged, [linuxbrew](https://brew.sh/) is a good alternative: `brew install fastfetch`
|
If fastfetch is not packaged for your distro or an outdated version is packaged, [linuxbrew](https://brew.sh/) is a good alternative: `brew install fastfetch`
|
||||||
|
|
||||||
### macOS
|
### macOS
|
||||||
@@ -95,18 +97,6 @@ Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki fo
|
|||||||
|
|
||||||
Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||||
|
|
||||||
|
|
||||||
## Packaging
|
|
||||||
|
|
||||||
### Repositories
|
|
||||||
|
|
||||||
[](https://repology.org/project/fastfetch/versions)
|
|
||||||
|
|
||||||
### Manual
|
|
||||||
|
|
||||||
* DEB / RPM package: `cmake --build . --target package`
|
|
||||||
* Install directly: `cmake --install . --prefix /usr/local`
|
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### Q: Neofetch is good enough. Why do I need fastfetch?
|
### Q: Neofetch is good enough. Why do I need fastfetch?
|
||||||
|
|||||||
+119
-428
@@ -1,430 +1,121 @@
|
|||||||
__fastfetch_complete_help()
|
#!/usr/bin/env bash
|
||||||
{
|
|
||||||
local __ff_helps=(
|
_fastfetch() {
|
||||||
"color"
|
# Use Bash built-in variables directly
|
||||||
"format"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
"config"
|
local prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
"os-format"
|
|
||||||
"host-format"
|
# Check if Python is available
|
||||||
"kernel-format"
|
if ! command -v python3 &>/dev/null; then
|
||||||
"uptime-format"
|
return
|
||||||
"processes-format"
|
fi
|
||||||
"packages-format"
|
|
||||||
"shell-format"
|
# Handle standard completion cases
|
||||||
"display-format"
|
case "$prev" in
|
||||||
"de-format"
|
--color|--color-keys|--color-title|--color-output|--color-separator|--*-color|--*-key-color|--*-output-color|--logo-color-[1-9]|--percent-color-*|--temp-color-*)
|
||||||
"wm-format"
|
local -a colors=("black" "red" "green" "yellow" "blue" "magenta" "cyan" "white" "default")
|
||||||
"wmtheme-format"
|
COMPREPLY=($(compgen -W "${colors[*]}" -- "$cur"))
|
||||||
"theme-format"
|
return
|
||||||
"icons-format"
|
;;
|
||||||
"font-format"
|
--logo|-l)
|
||||||
"cursor-format"
|
local -a logos
|
||||||
"terminal-format"
|
readarray -t logos < <(fastfetch --list-logos autocompletion 2>/dev/null)
|
||||||
"terminalfont-format"
|
logos+=("none" "small")
|
||||||
"cpu-format"
|
COMPREPLY=($(compgen -W "${logos[*]}" -- "$cur"))
|
||||||
"cpuusage-format"
|
return
|
||||||
"gpu-format"
|
;;
|
||||||
"memory-format"
|
--config|-c)
|
||||||
"swap-format"
|
local -a presets
|
||||||
"disk-format"
|
readarray -t presets < <(fastfetch --list-presets autocompletion 2>/dev/null)
|
||||||
"battery-format"
|
presets+=("none")
|
||||||
"poweradapter-format"
|
COMPREPLY=($(compgen -W "${presets[*]}" -- "$cur"))
|
||||||
"locale-format"
|
# Also allow file path completion
|
||||||
"localip-format"
|
if type _filedir &>/dev/null; then
|
||||||
"publicip-format"
|
_filedir
|
||||||
"player-format"
|
elif type compgen &>/dev/null; then
|
||||||
"media-format"
|
COMPREPLY+=($(compgen -f -- "$cur"))
|
||||||
"datetime-format"
|
fi
|
||||||
"date-format"
|
return
|
||||||
"time-format"
|
;;
|
||||||
"vulkan-format"
|
--structure|-s)
|
||||||
"opengl-format"
|
# Get all module names in lowercase only
|
||||||
"opencl-format"
|
local -a structures
|
||||||
"bluetooth-format"
|
readarray -t structures < <(fastfetch --list-modules autocompletion 2>/dev/null | cut -d':' -f1 | tr '[:upper:]' '[:lower:]')
|
||||||
)
|
COMPREPLY=($(compgen -W "${structures[*]}" -- "$cur"))
|
||||||
COMPREPLY=($(compgen -W "${__ff_helps[*]}" -- "$CURRENT_WORD"))
|
return
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
local -a modules
|
||||||
|
readarray -t modules < <(fastfetch --list-modules autocompletion 2>/dev/null)
|
||||||
|
# Convert to lowercase and keep only module names
|
||||||
|
local -a module_names=()
|
||||||
|
for module in "${modules[@]}"; do
|
||||||
|
module_names+=($(echo "$module" | cut -d':' -f1 | tr '[:upper:]' '[:lower:]')-format)
|
||||||
|
done
|
||||||
|
module_names+=("format" "color")
|
||||||
|
COMPREPLY=($(compgen -W "${module_names[*]}" -- "$cur"))
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
--format)
|
||||||
|
COMPREPLY=($(compgen -W "json default" -- "$cur"))
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
--*-format)
|
||||||
|
# Format string completion, handle spaces
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
--*path*|--*file*|--gen-config*|--*data*)
|
||||||
|
# File path completion
|
||||||
|
if type _filedir &>/dev/null; then
|
||||||
|
_filedir
|
||||||
|
elif type compgen &>/dev/null; then
|
||||||
|
COMPREPLY=($(compgen -f -- "$cur"))
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If not a special option, generate all possible options
|
||||||
|
if [[ "$cur" == -* ]]; then
|
||||||
|
local -a opts
|
||||||
|
readarray -t opts < <(python3 - "$cur" <<'EOF'
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def main(current):
|
||||||
|
try:
|
||||||
|
# Use fastfetch --help-raw to get option data
|
||||||
|
output = subprocess.check_output(['fastfetch', '--help-raw'], stderr=subprocess.DEVNULL)
|
||||||
|
data = json.loads(output)
|
||||||
|
|
||||||
|
for category in data.values():
|
||||||
|
for flag in category:
|
||||||
|
if flag.get("pseudo", False):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "short" in flag:
|
||||||
|
print(f"-{flag['short']}")
|
||||||
|
|
||||||
|
if "long" in flag:
|
||||||
|
if flag["long"] == "logo-color-[1-9]":
|
||||||
|
for i in range(1, 10):
|
||||||
|
print(f"--logo-color-{i}")
|
||||||
|
else:
|
||||||
|
print(f"--{flag['long']}")
|
||||||
|
except Exception:
|
||||||
|
# If error occurs, return no options
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv[1])
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
COMPREPLY=($(compgen -W "${opts[*]}" -- "$cur"))
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
__fastfetch_complete_bool()
|
# Register completion
|
||||||
{
|
complete -F _fastfetch fastfetch
|
||||||
COMPREPLY=($(compgen -W "true false" -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_string()
|
|
||||||
{
|
|
||||||
if [[ $CURRENT_WORD != "" ]]; then
|
|
||||||
COMPREPLY=("$CURRENT_WORD")
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_path()
|
|
||||||
{
|
|
||||||
COMPREPLY=($(compgen -A file -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_logo()
|
|
||||||
{
|
|
||||||
COMPREPLY=($(compgen -W "$(fastfetch --list-logos autocompletion)" -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_logo_type()
|
|
||||||
{
|
|
||||||
local __ff_logo_types=(
|
|
||||||
"auto"
|
|
||||||
"builtin"
|
|
||||||
"file"
|
|
||||||
"raw"
|
|
||||||
"sixel"
|
|
||||||
"kitty"
|
|
||||||
"chafa"
|
|
||||||
)
|
|
||||||
COMPREPLY=($(compgen -W "${__ff_logo_types[*]}" -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_binary_prefix()
|
|
||||||
{
|
|
||||||
local __ff_size_binary_prefixes=(
|
|
||||||
"iec"
|
|
||||||
"si"
|
|
||||||
"jedec"
|
|
||||||
)
|
|
||||||
COMPREPLY=($(compgen -W "${__ff_size_binary_prefixes[*]}" -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_gl()
|
|
||||||
{
|
|
||||||
local __ff_gl_types=(
|
|
||||||
"auto"
|
|
||||||
"egl"
|
|
||||||
"glx"
|
|
||||||
"osmesa"
|
|
||||||
)
|
|
||||||
COMPREPLY=($(compgen -W "${__ff_gl_types[*]}" -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_complete_option()
|
|
||||||
{
|
|
||||||
local FF_OPTIONS_ALL=(
|
|
||||||
"${FF_OPTIONS_BOOL[@]}"
|
|
||||||
"${FF_OPTIONS_STRING[@]}"
|
|
||||||
"${FF_OPTIONS_PATH[@]}"
|
|
||||||
"${FF_OPTIONS_LOGO[@]}"
|
|
||||||
"${FF_OPTIONS_LOGO_TYPE[@]}"
|
|
||||||
"${FF_OPTIONS_BINARY_PREFIX[@]}"
|
|
||||||
"${FF_OPTIONS_OPENGL[@]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ $WORD_COUND -lt 3 ]]; then
|
|
||||||
FF_OPTIONS_ALL+=(
|
|
||||||
"${FF_OPTIONS_SINGLE[@]}"
|
|
||||||
"${FF_OPTIONS_HELP[@]}"
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
|
|
||||||
for ff_word in ${COMP_WORDS[@]}; do
|
|
||||||
if [[ $ff_word == $CURRENT_WORD ]]; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
FF_OPTIONS_ALL=("${FF_OPTIONS_ALL[@]/$ff_word}")
|
|
||||||
done
|
|
||||||
|
|
||||||
COMPREPLY=($(compgen -W "${FF_OPTIONS_ALL[*]}" -- "$CURRENT_WORD"))
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_previous_matches()
|
|
||||||
{
|
|
||||||
for ff_option in "$@"; do
|
|
||||||
if [[ $ff_option == "$PREVIOUS_WORD" ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
__fastfetch_completion()
|
|
||||||
{
|
|
||||||
local CURRENT_WORD="${COMP_WORDS[$COMP_CWORD]}"
|
|
||||||
local PREVIOUS_WORD="${COMP_WORDS[$COMP_CWORD - 1]}"
|
|
||||||
local WORD_COUND="${#COMP_WORDS[@]}"
|
|
||||||
|
|
||||||
local FF_OPTIONS_SINGLE=(
|
|
||||||
"-v"
|
|
||||||
"--version"
|
|
||||||
"--list-logos"
|
|
||||||
"--list-modules"
|
|
||||||
"--list-presets"
|
|
||||||
"--list-features"
|
|
||||||
"--print-logos"
|
|
||||||
"--print-config-system"
|
|
||||||
"--print-config-user"
|
|
||||||
"--print-structure"
|
|
||||||
"--gen-config"
|
|
||||||
"--gen-config-force"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_HELP=(
|
|
||||||
"-h"
|
|
||||||
"--help"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_BOOL=(
|
|
||||||
"-r"
|
|
||||||
"--show-errors"
|
|
||||||
"--logo-print-remaining"
|
|
||||||
"--multithreading"
|
|
||||||
"--stat"
|
|
||||||
"--allow-slow-operations"
|
|
||||||
"--disable-linewrap"
|
|
||||||
"--hide-cursor"
|
|
||||||
"--cpu-temp"
|
|
||||||
"--gpu-temp"
|
|
||||||
"--battery-temp"
|
|
||||||
"--display-precise-refresh-rate"
|
|
||||||
"--localip-show-ipv4"
|
|
||||||
"--localip-show-ipv6"
|
|
||||||
"--localip-show-flags"
|
|
||||||
"--localip-show-loop"
|
|
||||||
"--localip-show-mtu"
|
|
||||||
"--localip-show-speed"
|
|
||||||
"--localip-name-prefix"
|
|
||||||
"--localip-compact-type"
|
|
||||||
"--escape-bedrock"
|
|
||||||
"--pipe"
|
|
||||||
"--title-fqdn"
|
|
||||||
"--disk-folders"
|
|
||||||
"--disk-show-external"
|
|
||||||
"--disk-show-hidden"
|
|
||||||
"--disk-show-subvolumes"
|
|
||||||
"--gpu-hide-integrated"
|
|
||||||
"--gpu-hide-discrete"
|
|
||||||
"--gpu-force-method"
|
|
||||||
"--disk-show-unknown"
|
|
||||||
"--bluetooth-show-disconnected"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_STRING=(
|
|
||||||
"--logo-type"
|
|
||||||
"--logo-padding"
|
|
||||||
"--logo-padding-left"
|
|
||||||
"--logo-padding-right"
|
|
||||||
"--logo-padding-top"
|
|
||||||
"--logo-color-1"
|
|
||||||
"--logo-color-2"
|
|
||||||
"--logo-color-3"
|
|
||||||
"--logo-color-4"
|
|
||||||
"--logo-color-5"
|
|
||||||
"--logo-color-6"
|
|
||||||
"--logo-color-7"
|
|
||||||
"--logo-color-8"
|
|
||||||
"--logo-color-9"
|
|
||||||
"--logo-width"
|
|
||||||
"--logo-height"
|
|
||||||
"--color"
|
|
||||||
"--color-keys"
|
|
||||||
"--color-title"
|
|
||||||
"--display-compact-type"
|
|
||||||
"--separator"
|
|
||||||
"-s"
|
|
||||||
"--structure"
|
|
||||||
"--player-name"
|
|
||||||
"--percent-type"
|
|
||||||
"--publicip-url"
|
|
||||||
"--publicip-timeout"
|
|
||||||
"--weather-output-format"
|
|
||||||
"--weather-timeout"
|
|
||||||
"--os-key"
|
|
||||||
"--os-format"
|
|
||||||
"--os-key-color"
|
|
||||||
"--host-key"
|
|
||||||
"--host-format"
|
|
||||||
"--host-key-color"
|
|
||||||
"--kernel-key"
|
|
||||||
"--kernel-format"
|
|
||||||
"--kernel-key-color"
|
|
||||||
"--uptime-key"
|
|
||||||
"--uptime-format"
|
|
||||||
"--uptime-key-color"
|
|
||||||
"--processes-key"
|
|
||||||
"--processes-format"
|
|
||||||
"--processes-key-color"
|
|
||||||
"--packages-key"
|
|
||||||
"--packages-format"
|
|
||||||
"--packages-key-color"
|
|
||||||
"--shell-key"
|
|
||||||
"--shell-format"
|
|
||||||
"--shell-key-color"
|
|
||||||
"--display-key"
|
|
||||||
"--display-format"
|
|
||||||
"--display-key-color"
|
|
||||||
"--de-key"
|
|
||||||
"--de-format"
|
|
||||||
"--de-key-color"
|
|
||||||
"--wm-key"
|
|
||||||
"--wm-format"
|
|
||||||
"--wm-key-color"
|
|
||||||
"--wmtheme-key"
|
|
||||||
"--wmtheme-format"
|
|
||||||
"--wmtheme-key-color"
|
|
||||||
"--theme-key"
|
|
||||||
"--theme-format"
|
|
||||||
"--theme-key-color"
|
|
||||||
"--icons-key"
|
|
||||||
"--icons-format"
|
|
||||||
"--icons-key-color"
|
|
||||||
"--font-key"
|
|
||||||
"--font-format"
|
|
||||||
"--font-key-color"
|
|
||||||
"--cursor-key"
|
|
||||||
"--cursor-format"
|
|
||||||
"--cursor-key-color"
|
|
||||||
"--terminal-key"
|
|
||||||
"--terminal-format"
|
|
||||||
"--terminal-key-color"
|
|
||||||
"--terminalfont-key"
|
|
||||||
"--terminalfont-format"
|
|
||||||
"--terminalfont-key-color"
|
|
||||||
"--cpu-key"
|
|
||||||
"--cpu-format"
|
|
||||||
"--cpu-key-color"
|
|
||||||
"--cpu-useage-key"
|
|
||||||
"--cpu-useage-format"
|
|
||||||
"--cpu-useage-key-color"
|
|
||||||
"--gpu-key"
|
|
||||||
"--gpu-format"
|
|
||||||
"--gpu-key-color"
|
|
||||||
"--memory-key"
|
|
||||||
"--memory-format"
|
|
||||||
"--memory-key-color"
|
|
||||||
"--swap-key"
|
|
||||||
"--swap-format"
|
|
||||||
"--swap-key-color"
|
|
||||||
"--disk-key"
|
|
||||||
"--disk-format"
|
|
||||||
"--disk-key-color"
|
|
||||||
"--battery-key"
|
|
||||||
"--battery-format"
|
|
||||||
"--battery-key-color"
|
|
||||||
"--poweradapter-key"
|
|
||||||
"--poweradapter-format"
|
|
||||||
"--poweradapter-key-color"
|
|
||||||
"--locale-key"
|
|
||||||
"--locale-format"
|
|
||||||
"--locale-key-color"
|
|
||||||
"--localip-key"
|
|
||||||
"--localip-format"
|
|
||||||
"--localip-key-color"
|
|
||||||
"--publicip-key"
|
|
||||||
"--publicip-format"
|
|
||||||
"--publicip-key-color"
|
|
||||||
"--wifi-key"
|
|
||||||
"--wifi-format"
|
|
||||||
"--wifi-key-color"
|
|
||||||
"--weather-key"
|
|
||||||
"--weather-format"
|
|
||||||
"--weather-key-color"
|
|
||||||
"--player-key"
|
|
||||||
"--player-format"
|
|
||||||
"--player-key-color"
|
|
||||||
"--media-key"
|
|
||||||
"--media-format"
|
|
||||||
"--media-key-color"
|
|
||||||
"--datetime-key"
|
|
||||||
"--datetime-format"
|
|
||||||
"--datetime-key-color"
|
|
||||||
"--date-key"
|
|
||||||
"--date-format"
|
|
||||||
"--date-key-color"
|
|
||||||
"--time-key"
|
|
||||||
"--time-format"
|
|
||||||
"--time-key-color"
|
|
||||||
"--vulkan-key"
|
|
||||||
"--vulkan-format"
|
|
||||||
"--vulkan-key-color"
|
|
||||||
"--opengl-key"
|
|
||||||
"--opengl-format"
|
|
||||||
"--opengl-key-color"
|
|
||||||
"--opencl-key"
|
|
||||||
"--opencl-format"
|
|
||||||
"--opencl-key-color"
|
|
||||||
"--users-key"
|
|
||||||
"--users-format"
|
|
||||||
"--users-key-color"
|
|
||||||
"--users-myself-only"
|
|
||||||
"--bluetooth-key"
|
|
||||||
"--bluetooth-format"
|
|
||||||
"--bluetooth-key-color"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_PATH=(
|
|
||||||
"-c"
|
|
||||||
"--config"
|
|
||||||
"--lib-vulkan"
|
|
||||||
"--lib-wayland"
|
|
||||||
"--lib-xcb-randr"
|
|
||||||
"--lib-xcb"
|
|
||||||
"--lib-xrandr"
|
|
||||||
"--lib-X11"
|
|
||||||
"--lib-gio"
|
|
||||||
"--lib-dconf"
|
|
||||||
"--lib-dbus"
|
|
||||||
"--lib-xfconf"
|
|
||||||
"--lib-sqlite3"
|
|
||||||
"--lib-rpm"
|
|
||||||
"--lib-imagemagick"
|
|
||||||
"--lib-z"
|
|
||||||
"--lib-chafa"
|
|
||||||
"--lib-egl"
|
|
||||||
"--lib-glx"
|
|
||||||
"--lib-osmesa"
|
|
||||||
"--lib-opencl"
|
|
||||||
"--lib-pulse"
|
|
||||||
"--lib-ddcutil"
|
|
||||||
"--lib-nm"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_LOGO=(
|
|
||||||
"-l"
|
|
||||||
"--logo"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_LOGO_TYPE=(
|
|
||||||
"--logo-type"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_BINARY_PREFIX=(
|
|
||||||
"--binary-prefix"
|
|
||||||
)
|
|
||||||
|
|
||||||
local FF_OPTIONS_OPENGL=(
|
|
||||||
"--opengl-type"
|
|
||||||
)
|
|
||||||
|
|
||||||
if __fastfetch_previous_matches "${FF_OPTIONS_SINGLE[@]}"; then
|
|
||||||
return
|
|
||||||
elif [[ $WORD_COUND -gt 3 && ( ${COMP_WORDS[$COMP_CWORD - 2]} == "--help" || ${COMP_WORDS[$COMP_CWORD - 2]} == "-h" ) ]]; then
|
|
||||||
return
|
|
||||||
elif [[ $CURRENT_WORD == "-"* ]]; then
|
|
||||||
__fastfetch_complete_option
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_HELP[@]}"; then
|
|
||||||
__fastfetch_complete_help
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_BOOL[@]}"; then
|
|
||||||
__fastfetch_complete_bool
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_STRING[@]}"; then
|
|
||||||
__fastfetch_complete_string
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_PATH[@]}"; then
|
|
||||||
__fastfetch_complete_path
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_LOGO[@]}"; then
|
|
||||||
__fastfetch_complete_logo
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_LOGO_TYPE[@]}"; then
|
|
||||||
__fastfetch_complete_logo_type
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_BINARY_PREFIX[@]}"; then
|
|
||||||
__fastfetch_complete_binary_prefix
|
|
||||||
elif __fastfetch_previous_matches "${FF_OPTIONS_OPENGL[@]}"; then
|
|
||||||
__fastfetch_complete_gl
|
|
||||||
else
|
|
||||||
__fastfetch_complete_option
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F __fastfetch_completion fastfetch
|
|
||||||
|
|||||||
Vendored
+42
@@ -1,3 +1,45 @@
|
|||||||
|
fastfetch (2.40.0) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.40.0
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Thu, 03 Apr 2025 08:46:54 +0800
|
||||||
|
|
||||||
|
fastfetch (2.39.1) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.39.1
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Fri, 21 Mar 2025 11:02:19 +0800
|
||||||
|
|
||||||
|
fastfetch (2.39.0ubuntu1) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Remove unwanted debugging code
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Thu, 20 Mar 2025 10:39:22 +0800
|
||||||
|
|
||||||
|
fastfetch (2.39.0) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.39.0
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Thu, 20 Mar 2025 10:35:18 +0800
|
||||||
|
|
||||||
|
fastfetch (2.38.0) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.38.0
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Wed, 05 Mar 2025 14:56:24 +0800
|
||||||
|
|
||||||
|
fastfetch (2.37.0) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.37.0
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Wed, 19 Feb 2025 15:43:42 +0800
|
||||||
|
|
||||||
|
fastfetch (2.36.1) jammy; urgency=medium
|
||||||
|
|
||||||
|
* Update to 2.36.1
|
||||||
|
|
||||||
|
-- Carter Li <zhangsongcui@live.cn> Tue, 11 Feb 2025 13:39:55 +0800
|
||||||
|
|
||||||
fastfetch (2.36.0) jammy; urgency=medium
|
fastfetch (2.36.0) jammy; urgency=medium
|
||||||
|
|
||||||
* Update to 2.36.0
|
* Update to 2.36.0
|
||||||
|
|||||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ Source: fastfetch
|
|||||||
Section: universe/utils
|
Section: universe/utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Carter Li <zhangsongcui@live.cn>
|
Maintainer: Carter Li <zhangsongcui@live.cn>
|
||||||
Build-Depends: libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libxfconf-0-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, libosmesa6-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, directx-headers-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build
|
Build-Depends: libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libxfconf-0-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, directx-headers-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build
|
||||||
Standards-Version: 4.0.0
|
Standards-Version: 4.0.0
|
||||||
Homepage: https://github.com/fastfetch-cli/fastfetch
|
Homepage: https://github.com/fastfetch-cli/fastfetch
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
fastfetch_2.36.0_source.buildinfo universe/utils optional
|
fastfetch_2.40.0_source.buildinfo universe/utils optional
|
||||||
|
|||||||
+10
-9
@@ -183,7 +183,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"diskFormat": {
|
"diskFormat": {
|
||||||
"description": "Output format of the module `Disk`. See `-h format` for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem\n 10. {name}: Label / name\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation",
|
"description": "Output format of the module `Disk`. See `-h format` for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem\n 10. {name}: Label / name\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter\n 21. {mount-from}: Mount from (device path)",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"diskioFormat": {
|
"diskioFormat": {
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"gpuFormat": {
|
"gpuFormat": {
|
||||||
"description": "Output format of the module `GPU`. See `-h format` for formatting syntax\n 1. {vendor}: GPU vendor\n 2. {name}: GPU name\n 3. {driver}: GPU driver\n 4. {temperature}: GPU temperature\n 5. {core-count}: GPU core count\n 6. {type}: GPU type\n 7. {dedicated-total}: GPU total dedicated memory\n 8. {dedicated-used}: GPU used dedicated memory\n 9. {shared-total}: GPU total shared memory\n 10. {shared-used}: GPU used shared memory\n 11. {platform-api}: The platform API used when detecting the GPU\n 12. {frequency}: Current frequency in GHz\n 13. {index}: GPU vendor specific index",
|
"description": "Output format of the module `GPU`. See `-h format` for formatting syntax\n 1. {vendor}: GPU vendor\n 2. {name}: GPU name\n 3. {driver}: GPU driver\n 4. {temperature}: GPU temperature\n 5. {core-count}: GPU core count\n 6. {type}: GPU type\n 7. {dedicated-total}: GPU total dedicated memory\n 8. {dedicated-used}: GPU used dedicated memory\n 9. {shared-total}: GPU total shared memory\n 10. {shared-used}: GPU used shared memory\n 11. {platform-api}: The platform API used when detecting the GPU\n 12. {frequency}: Current frequency in GHz\n 13. {index}: GPU vendor specific index\n 14. {dedicated-percentage-num}: Dedicated memory usage percentage num\n 15. {dedicated-percentage-bar}: Dedicated memory usage percentage bar\n 16. {shared-percentage-num}: Shared memory usage percentage num\n 17. {shared-percentage-bar}: Shared memory usage percentage bar\n 18. {core-usage-num}: Core usage percentage num (supports Nvidia & Apple GPU only)\n 19. {core-usage-bar}: Core usage percentage bar (supports Nvidia & Apple GPU only)",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"hostFormat": {
|
"hostFormat": {
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"packagesFormat": {
|
"packagesFormat": {
|
||||||
"description": "Output format of the module `Packages`. See `-h format` for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop}: Number of scoop packages\n 21. {choco}: Number of choco packages\n 22. {pkgtool}: Number of pkgtool packages\n 23. {paludis}: Number of paludis packages\n 24. {winget}: Number of winget packages\n 25. {opkg}: Number of opkg packages\n 26. {am-system}: Number of am-system packages\n 27. {sorcery}: Number of sorcery packages\n 28. {lpkg}: Number of lpkg packages\n 29. {lpkgbuild}: Number of lpkgbuild packages\n 30. {guix-system}: Number of guix-system packages\n 31. {guix-user}: Number of guix-user packages\n 32. {guix-home}: Number of guix-home packages\n 33. {linglong}: Number of linglong packages\n 34. {pacstall}: Number of pacstall packages\n 35. {mport}: Number of mport packages\n 36. {qi}: Number of qi packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {nix-all}: Total number of all nix packages\n 40. {flatpak-all}: Total number of all flatpak app packages\n 41. {brew-all}: Total number of all brew packages\n 42. {guix-all}: Total number of all guix packages",
|
"description": "Output format of the module `Packages`. See `-h format` for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop}: Number of scoop packages\n 21. {choco}: Number of choco packages\n 22. {pkgtool}: Number of pkgtool packages\n 23. {paludis}: Number of paludis packages\n 24. {winget}: Number of winget packages\n 25. {opkg}: Number of opkg packages\n 26. {am-system}: Number of am-system packages\n 27. {sorcery}: Number of sorcery packages\n 28. {lpkg}: Number of lpkg packages\n 29. {lpkgbuild}: Number of lpkgbuild packages\n 30. {guix-system}: Number of guix-system packages\n 31. {guix-user}: Number of guix-user packages\n 32. {guix-home}: Number of guix-home packages\n 33. {linglong}: Number of linglong packages\n 34. {pacstall}: Number of pacstall packages\n 35. {mport}: Number of mport packages\n 36. {qi}: Number of qi packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {nix-all}: Total number of all nix packages\n 43. {flatpak-all}: Total number of all flatpak app packages\n 44. {brew-all}: Total number of all brew packages\n 45. {guix-all}: Total number of all guix packages\n 46. {hpkg-all}: Total number of all hpkg packages",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"physicaldiskFormat": {
|
"physicaldiskFormat": {
|
||||||
@@ -786,11 +786,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"const": "si",
|
"const": "si",
|
||||||
"description": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ..."
|
"description": "1000 Bytes = 1 kB, 1000 kB = 1 MB, ..."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"const": "jedec",
|
"const": "jedec",
|
||||||
"description": "1024 Bytes = 1 kB, 1024 K = 1 MB, ..."
|
"description": "1024 Bytes = 1 KB, 1024 KB = 1 MB, ..."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -817,8 +817,8 @@
|
|||||||
"unit": {
|
"unit": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Set the unit of the temperature",
|
"description": "Set the unit of the temperature",
|
||||||
"enum": ["CELSIUS", "C", "FAHRENHEIT", "F", "KELVIN", "K"],
|
"enum": ["D", "Default", "Celsius", "C", "Fahrenheit", "F", "Kelvin", "K"],
|
||||||
"default": "C"
|
"default": "D"
|
||||||
},
|
},
|
||||||
"ndigits": {
|
"ndigits": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
@@ -2563,8 +2563,7 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"auto",
|
"auto",
|
||||||
"egl",
|
"egl",
|
||||||
"glx",
|
"glx"
|
||||||
"osmesa"
|
|
||||||
],
|
],
|
||||||
"default": "auto"
|
"default": "auto"
|
||||||
},
|
},
|
||||||
@@ -2641,6 +2640,7 @@
|
|||||||
"eopkg",
|
"eopkg",
|
||||||
"flatpak",
|
"flatpak",
|
||||||
"guix",
|
"guix",
|
||||||
|
"hpkg",
|
||||||
"linglong",
|
"linglong",
|
||||||
"lpkg",
|
"lpkg",
|
||||||
"lpkgbuild",
|
"lpkgbuild",
|
||||||
@@ -2651,6 +2651,7 @@
|
|||||||
"pacman",
|
"pacman",
|
||||||
"pacstall",
|
"pacstall",
|
||||||
"paludis",
|
"paludis",
|
||||||
|
"pisi",
|
||||||
"pkg",
|
"pkg",
|
||||||
"pkgtool",
|
"pkgtool",
|
||||||
"qi",
|
"qi",
|
||||||
|
|||||||
@@ -90,6 +90,8 @@
|
|||||||
"sound",
|
"sound",
|
||||||
"camera",
|
"camera",
|
||||||
"gamepad",
|
"gamepad",
|
||||||
|
"mouse",
|
||||||
|
"keyboard",
|
||||||
{
|
{
|
||||||
"type": "weather",
|
"type": "weather",
|
||||||
"timeout": 1000
|
"timeout": 1000
|
||||||
|
|||||||
@@ -92,6 +92,8 @@
|
|||||||
"sound",
|
"sound",
|
||||||
"camera",
|
"camera",
|
||||||
"gamepad",
|
"gamepad",
|
||||||
|
"mouse",
|
||||||
|
"keyboard",
|
||||||
{
|
{
|
||||||
"type": "weather",
|
"type": "weather",
|
||||||
"timeout": 1000
|
"timeout": 1000
|
||||||
|
|||||||
+11
-11
@@ -28,38 +28,38 @@
|
|||||||
{
|
{
|
||||||
"type": "title",
|
"type": "title",
|
||||||
"key": "{#90}{$1}│ {#92}User {#90}│",
|
"key": "{#90}{$1}│ {#92}User {#90}│",
|
||||||
"format": "{$2}{$3}{user-name} {#2}[{home-dir}]"
|
"format": "{$2}{$3}{user-name} {#2}[{home-dir}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "users",
|
"type": "users",
|
||||||
"key": "{#90}{$1}│ {#92}Users {#90}│",
|
"key": "{#90}{$1}│ {#92}Users {#90}│",
|
||||||
"myselfOnly": false,
|
"myselfOnly": false,
|
||||||
"format": "{$2}{$3}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} {#2}[Login time: {login-time}]",
|
"format": "{$2}{$3}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} [Login time: {login-time}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "datetime",
|
"type": "datetime",
|
||||||
"key": "{#90}{$1}│ {#92}Datetime {#90}│",
|
"key": "{#90}{$1}│ {#92}Datetime {#90}│",
|
||||||
"format": "{$2}{$3}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} {#2}{weekday} {#2}[W{week}] {#2}[UTC{offset-from-utc}]"
|
"format": "{$2}{$3}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} [{weekday}] [W{week}] [UTC{offset-from-utc}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "title",
|
"type": "title",
|
||||||
"key": "{#90}{$1}│ {#93}Host: {#90}│",
|
"key": "{#90}{$1}│ {#93}Host {#90}│",
|
||||||
"format": "{$2}{$3}{#1}{#36}{host-name}"
|
"format": "{$2}{$3}{host-name}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "host",
|
"type": "host",
|
||||||
"key": "{#90}{$1}│ {#93}Machine {#90}│",
|
"key": "{#90}{$1}│ {#93}Machine {#90}│",
|
||||||
"format": "{$2}{$3}{name} {#2}{version}"
|
"format": "{$2}{$3}{name} {#2}{version}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "os",
|
"type": "os",
|
||||||
"key": "{#90}{$1}│ {#93}OS {#90}│",
|
"key": "{#90}{$1}│ {#93}OS {#90}│",
|
||||||
"format": "{$2}{$3}{pretty-name} {codename} {#2}[v{version}] {#2}[{arch}]"
|
"format": "{$2}{$3}{?pretty-name}{pretty-name}{?}{/pretty-name}{name}{/} {codename} {#2}[v{version}] [{arch}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "kernel",
|
"type": "kernel",
|
||||||
"key": "{#90}{$1}│ {#93}Kernel {#90}│",
|
"key": "{#90}{$1}│ {#93}Kernel {#90}│",
|
||||||
"format": "{$2}{$3}{sysname} {#2}[v{release}]"
|
"format": "{$2}{$3}{sysname} {#2}[v{release}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "uptime",
|
"type": "uptime",
|
||||||
@@ -71,14 +71,14 @@
|
|||||||
"key": "{#90}{$1}│ {#91}CPU {#90}│",
|
"key": "{#90}{$1}│ {#91}CPU {#90}│",
|
||||||
"showPeCoreCount": true,
|
"showPeCoreCount": true,
|
||||||
"temp": true,
|
"temp": true,
|
||||||
"format": "{$2}{$3}{name} {#2}[C:{core-types}] {#2}[{freq-max}]"
|
"format": "{$2}{$3}{name} {#2}[C:{core-types}] [{freq-max}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "gpu",
|
"type": "gpu",
|
||||||
"key": "{#90}{$1}│ {#91}GPU {#90}│",
|
"key": "{#90}{$1}│ {#91}GPU {#90}│",
|
||||||
"detectionMethod": "auto",
|
"detectionMethod": "auto",
|
||||||
"driverSpecific": true,
|
"driverSpecific": true,
|
||||||
"format": "{$2}{$3}{name} {#2}[C:{core-count}] {#2}[{type}]"
|
"format": "{$2}{$3}{name} {#2}[C:{core-count}]{?frequency} [{frequency}]{?} [{type}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "memory",
|
"type": "memory",
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
{
|
{
|
||||||
"type": "terminal",
|
"type": "terminal",
|
||||||
"key": "{#90}{$1}│ {#95}Terminal {#90}│",
|
"key": "{#90}{$1}│ {#95}Terminal {#90}│",
|
||||||
"format": "{$2}{$3}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
"format": "{$2}{$3}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "terminalfont",
|
"type": "terminalfont",
|
||||||
|
|||||||
@@ -0,0 +1,241 @@
|
|||||||
|
// Based on #1576
|
||||||
|
{
|
||||||
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
|
"display": {
|
||||||
|
"color": {
|
||||||
|
"keys": "blue"
|
||||||
|
},
|
||||||
|
"separator": "",
|
||||||
|
"constants": [
|
||||||
|
"──────────────────────────────────────────────",
|
||||||
|
"\u001b[47D",
|
||||||
|
"\u001b[47C",
|
||||||
|
"\u001b[46C"
|
||||||
|
],
|
||||||
|
"brightColor": false
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"type": "version",
|
||||||
|
"key": "┌───────────────┬─{$1}┐\u001b[41D",
|
||||||
|
"format": "\u001b[1m{#keys} {1} - {2} "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "os",
|
||||||
|
"key": "│ {icon} \u001b[s{sysname}\u001b[u\u001b[10C│{$3}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "datetime",
|
||||||
|
"key": "│ {icon} Fetched │{$3}│{$2}",
|
||||||
|
"format": "{year}-{month-pretty}-{day-pretty} {hour-pretty}:{minute-pretty}:{second-pretty} {timezone-name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "locale",
|
||||||
|
"key": "│ {icon} Locale │{$3}│{$2}"
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hardware
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#cyan}┌──────────────┬{$1}┐{#keys}│\u001b[37D",
|
||||||
|
"format": "{#bright_cyan} Hardware "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "chassis",
|
||||||
|
"key": "│{#cyan}│ {icon} Chassis │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "memory",
|
||||||
|
"key": "│{#cyan}│ {icon} RAM │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "swap",
|
||||||
|
"key": "│{#cyan}│ {icon} SWAP │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "cpu",
|
||||||
|
"key": "│{#cyan}│ {icon} CPU │{$4}│{#keys}│{$2}",
|
||||||
|
"showPeCoreCount": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "gpu",
|
||||||
|
"key": "│{#cyan}│ {icon} GPU │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "disk",
|
||||||
|
"key": "│{#cyan}│ {icon} Disk │{$4}│{#keys}│{$2}",
|
||||||
|
"format": "{size-used} \/ {size-total} ({size-percentage}) - {filesystem}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "battery",
|
||||||
|
"key": "│{#cyan}│ {icon} Battery │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#cyan}└──────────────┴{$1}┘{#keys}│",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
// Desktop
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#green}┌──────────────┬{$1}┐{#keys}│\u001b[37D",
|
||||||
|
"format": "{#bright_green} Desktop "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "de",
|
||||||
|
"key": "│{#green}│ {icon} Desktop │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wm",
|
||||||
|
"key": "│{#green}│ {icon} Session │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "display",
|
||||||
|
"key": "│{#green}│ {icon} Display │{$4}│{#keys}│{$2}",
|
||||||
|
"compactType": "original-with-refresh-rate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "gpu",
|
||||||
|
"key": "│{#green}│ {icon} G-Driver │{$4}│{#keys}│{$2}",
|
||||||
|
"format": "{driver}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#green}└──────────────┴{$1}┘{#keys}│",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
// Terminal
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#yellow}┌──────────────┬{$1}┐{#keys}│\u001b[37D",
|
||||||
|
"format": "{#bright_yellow} Terminal "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"key": "│{#yellow}│ {icon} Shell │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "terminal",
|
||||||
|
"key": "│{#yellow}│ {icon} Terminal │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "terminalfont",
|
||||||
|
"key": "│{#yellow}│ {icon} Term Font │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "terminaltheme",
|
||||||
|
"key": "│{#yellow}│ {icon} Colors │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "packages",
|
||||||
|
"key": "│{#yellow}│ {icon} Packages │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#yellow}└──────────────┴{$1}┘{#keys}│",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
// Development
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#red}┌──────────────┬{$1}┐{#keys}│\u001b[39D",
|
||||||
|
"format": "{#bright_red} Development "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#red}│ {icon} Rust │{$4}│{#keys}│{$2}",
|
||||||
|
"text": "rustc --version | cut -d' ' -f2",
|
||||||
|
"format": "rustc {}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#red}│ {icon} Clang │{$4}│{#keys}│{$2}",
|
||||||
|
"text": "clang --version | head -1 | awk '{print $NF}'",
|
||||||
|
"format": "clang {}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#red}│ {icon} NodeJS │{$4}│{#keys}│{$2}",
|
||||||
|
"text": "node --version",
|
||||||
|
"format": "node {~1}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#red}│ {icon} Go │{$4}│{#keys}│{$2}",
|
||||||
|
"text": "go version | cut -d' ' -f3",
|
||||||
|
"format": "go {~2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#red}│ {icon} Zig │{$4}│{#keys}│{$2}",
|
||||||
|
"text": "zig version",
|
||||||
|
"format": "zig {}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "editor",
|
||||||
|
"key": "│{#red}│ {icon} Editor │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#red}│ {icon} Git │{$4}│{#keys}│{$2}",
|
||||||
|
"text": "git version",
|
||||||
|
"format": "git {~12}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "font",
|
||||||
|
"key": "│{#red}│ {icon} Interface │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#red}└──────────────┴{$1}┘{#keys}│",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
// Uptime
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#magenta}┌──────────────┬{$1}┐{#keys}│\u001b[36D",
|
||||||
|
"format": "{#bright_magenta} Uptime "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "uptime",
|
||||||
|
"key": "│{#magenta}│ {icon} Uptime │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "users",
|
||||||
|
"myselfOnly": true,
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#magenta}│ {icon} Login │{$4}│{#keys}│{$2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "disk",
|
||||||
|
"keyIcon": "",
|
||||||
|
"key": "│{#magenta}│ {icon} OS Age │{$4}│{#keys}│{$2}",
|
||||||
|
"folders": "/", // On macOS, "/System/Volumes/VM" works for me
|
||||||
|
"format": "{create-time:10} [{days} days]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "│{#magenta}└──────────────┴{$1}┘{#keys}│",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "└─────────────────{$1}┘",
|
||||||
|
"format": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
// End
|
||||||
|
"break",
|
||||||
|
"colors"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
// Modified from: 24.jsonc
|
||||||
|
{
|
||||||
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
|
"logo": {
|
||||||
|
"padding": {
|
||||||
|
"top": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
"separator": "",
|
||||||
|
"constants": [
|
||||||
|
// CONSTANT {$1} - VERTICAL BARS AT START AND 75th CHARACTERS FORWARD AND BACKWARD
|
||||||
|
"\u001b[90m│ │\u001b[60D\u001b[39m"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": [
|
||||||
|
// CUSTOM - Top UI bar
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "{#90}╭ Keys ───────╮",
|
||||||
|
"format": "{#90}╭ Values ────────────────────────────────────────────────────╮",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "title",
|
||||||
|
"key": "{#90}│ {#92}User {#90}│",
|
||||||
|
"format": "{$1}{user-name} {#2}[{home-dir}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "users",
|
||||||
|
"key": "{#90}│ {#92}Users {#90}│",
|
||||||
|
"myselfOnly": false,
|
||||||
|
"format": "{$1}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} [Login time: {login-time}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "datetime",
|
||||||
|
"key": "{#90}│ {#92}Datetime {#90}│",
|
||||||
|
"format": "{$1}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} {#2}[{weekday}] [W{week}] [UTC{offset-from-utc}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "title",
|
||||||
|
"key": "{#90}│ {#93}Host {#90}│",
|
||||||
|
"format": "{$1}{host-name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "host",
|
||||||
|
"key": "{#90}│ {#93}Machine {#90}│",
|
||||||
|
"format": "{$1}{name} {#2}{version}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "os",
|
||||||
|
"key": "{#90}│ {#93}OS {#90}│",
|
||||||
|
"format": "{$1}{?pretty-name}{pretty-name}{?}{/pretty-name}{name}{/} {codename} {#2}[v{version}] [{arch}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "kernel",
|
||||||
|
"key": "{#90}│ {#93}Kernel {#90}│",
|
||||||
|
"format": "{$1}{sysname} {#2}[v{release}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "uptime",
|
||||||
|
"key": "{#90}│ {#93}Uptime {#90}│",
|
||||||
|
"format": "{$1}{?days}{days} Days + {?}{hours}:{minutes}:{seconds}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "cpu",
|
||||||
|
"key": "{#90}│ {#91}CPU {#90}│",
|
||||||
|
"showPeCoreCount": true,
|
||||||
|
"temp": true,
|
||||||
|
"format": "{$1}{name} {#2}[C:{core-types}] [{freq-max}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "gpu",
|
||||||
|
"key": "{#90}│ {#91}GPU {#90}│",
|
||||||
|
"detectionMethod": "auto",
|
||||||
|
"driverSpecific": true,
|
||||||
|
"format": "{$1}{name} {#2}[C:{core-count}]{?frequency} [{frequency}]{?} {#2}[{type}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "memory",
|
||||||
|
"key": "{#90}│ {#91}Memory {#90}│",
|
||||||
|
"format": "{$1}{used} / {total} ({percentage})"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "disk",
|
||||||
|
"key": "{#90}│ {#91}Disk {#90}│",
|
||||||
|
"format": "{$1}{size-used} / {size-total} ({size-percentage})"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "poweradapter",
|
||||||
|
"key": "{#90}│ {#91}Power {#90}│",
|
||||||
|
"format": "{$1}{name}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "terminal",
|
||||||
|
"key": "{#90}│ {#95}Terminal {#90}│",
|
||||||
|
"format": "{$1}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "terminalfont",
|
||||||
|
"key": "{#90}│ {#95}Font {#90}│",
|
||||||
|
"format": "{$1}{name} {#2}[{size}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"key": "{#90}│ {#95}Shell {#90}│",
|
||||||
|
"format": "{$1}{pretty-name} {#2}[v{version}] [PID:{pid}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// localip IPv4
|
||||||
|
"type": "localip",
|
||||||
|
"key": "{#90}│ {#94}Local IPv4 {#90}│",
|
||||||
|
"showPrefixLen": true,
|
||||||
|
"showIpv4": true,
|
||||||
|
"showIpv6": false,
|
||||||
|
"showMtu": true,
|
||||||
|
"format": "{$1}{ifname}: {ipv4} {#2}[MTU:{mtu}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// localip IPv6
|
||||||
|
"type": "localip",
|
||||||
|
"key": "{#90}│ {#94}Local IPv6 {#90}│",
|
||||||
|
"showPrefixLen": true,
|
||||||
|
"showIpv4": false,
|
||||||
|
"showIpv6": true,
|
||||||
|
"showMtu": true,
|
||||||
|
"format": "{$1}{ifname}: {ipv6} {#2}[MTU:{mtu}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "publicip",
|
||||||
|
"key": "{#90}│ {#94}Public IPv4 {#90}│",
|
||||||
|
"ipv6": false,
|
||||||
|
"format": "{$1}{ip} {#2}[{location}]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "publicip",
|
||||||
|
"key": "{#90}│ {#94}Public IPv6 {#90}│",
|
||||||
|
"ipv6": true,
|
||||||
|
"format": "{$1}{ip} {#2}[{location}]"
|
||||||
|
},
|
||||||
|
// CUSTOM - Button UI bar
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": "{#90}╰─────────────╯",
|
||||||
|
"format": "{#90}╰────────────────────────────────────────────────────────────╯",
|
||||||
|
},
|
||||||
|
"break",
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"key": " ",
|
||||||
|
"format": "{#90}╭ Colors ───────────────────────────────────────────────────────────────────╮",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"format": "{#90}│ {#40} {#41} {#42} {#43} {#44} {#45} {#46} {#47} {#} {#90}│",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"format": "{#90}│ {#100} {#101} {#102} {#103} {#104} {#105} {#106} {#107} {#} {#90}│",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "custom",
|
||||||
|
"format": "{#90}╰───────────────────────────────────────────────────────────────────────────╯",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def main(amdgpu_ids_path: str):
|
||||||
|
with open(amdgpu_ids_path, 'r') as f:
|
||||||
|
full_text = f.read()
|
||||||
|
|
||||||
|
products = []
|
||||||
|
for line in full_text.split('\n'):
|
||||||
|
if not line or line[0] == '#' or not ',\t' in line:
|
||||||
|
continue
|
||||||
|
device, revision, name = line.split(',\t', maxsplit=2)
|
||||||
|
products.append((device, revision, name))
|
||||||
|
|
||||||
|
code = """\
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// https://opensource.org/license/mit
|
||||||
|
// Generated from https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef struct FFArmGpuProduct
|
||||||
|
{
|
||||||
|
const uint32_t id; // device << 8 | revision
|
||||||
|
const char* name;
|
||||||
|
} FFArmGpuProduct;
|
||||||
|
|
||||||
|
const FFArmGpuProduct ffAmdGpuProducts[] = {
|
||||||
|
"""
|
||||||
|
|
||||||
|
for device, revision, name in products:
|
||||||
|
code += f" {{ 0x{device} << 8 | 0x{revision}, \"{name}\" }},\n"
|
||||||
|
|
||||||
|
code += "};\n"
|
||||||
|
|
||||||
|
print(code)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
len(sys.argv) == 2 or sys.exit('Usage: gen-amdgpuids.py </path/to/amdgpu.ids>')
|
||||||
|
|
||||||
|
main(sys.argv[1])
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from requests import get as http_get
|
import sys
|
||||||
|
|
||||||
class PciDeviceModel:
|
class PciDeviceModel:
|
||||||
def __init__(self, id: int, name: str):
|
def __init__(self, id: int, name: str):
|
||||||
@@ -13,14 +13,10 @@ class PciVendorModel:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.devices = []
|
self.devices = []
|
||||||
|
|
||||||
def main(keep_vendor_list: set):
|
def main(keep_vendor_list: set, pci_ids_path: str):
|
||||||
vendors = []
|
vendors = []
|
||||||
try:
|
with open(pci_ids_path, 'r') as f:
|
||||||
with open('pci.ids', 'r') as f:
|
full_text = f.read()
|
||||||
full_text = f.read()
|
|
||||||
except FileNotFoundError:
|
|
||||||
response = http_get('https://pci-ids.ucw.cz/v2.2/pci.ids')
|
|
||||||
full_text = response.text
|
|
||||||
|
|
||||||
dev_list_text = full_text[:full_text.rfind('\n\n\n')] # remove known classes
|
dev_list_text = full_text[:full_text.rfind('\n\n\n')] # remove known classes
|
||||||
for line in dev_list_text.split('\n'):
|
for line in dev_list_text.split('\n'):
|
||||||
@@ -80,6 +76,8 @@ const FFPciVendor ffPciVendors[] = {{
|
|||||||
print(code)
|
print(code)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
len(sys.argv) == 2 or sys.exit('Usage: gen-pciids.py </path/to/pci.ids>')
|
||||||
|
|
||||||
# From <src/detection/gpu/gpu.c>
|
# From <src/detection/gpu/gpu.c>
|
||||||
main({
|
main({
|
||||||
0x106b, # Apple
|
0x106b, # Apple
|
||||||
@@ -94,4 +92,4 @@ if __name__ == '__main__':
|
|||||||
0x1ab8, # Parallel
|
0x1ab8, # Parallel
|
||||||
0x1414, # Microsoft
|
0x1414, # Microsoft
|
||||||
0x108e, # Oracle
|
0x108e, # Oracle
|
||||||
})
|
}, sys.argv[1])
|
||||||
|
|||||||
Vendored
-383
@@ -1,383 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
/// \file
|
|
||||||
/// \mainpage
|
|
||||||
/// AGS Library Overview
|
|
||||||
/// --------------------
|
|
||||||
/// This document provides an overview of the AGS (AMD GPU Services) library. The AGS library provides software developers with the ability to query
|
|
||||||
/// AMD GPU software and hardware state information that is not normally available through standard operating systems or graphic APIs.
|
|
||||||
///
|
|
||||||
/// The latest version of the API is publicly hosted here: https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/.
|
|
||||||
/// It is also worth checking http://gpuopen.com/gaming-product/amd-gpu-services-ags-library/ for any updates and articles on AGS.
|
|
||||||
/// \internal
|
|
||||||
/// Online documentation is publicly hosted here: http://gpuopen-librariesandsdks.github.io/ags/
|
|
||||||
/// \endinternal
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 6.2 since version 6.1
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 6.2 includes the following updates:
|
|
||||||
/// * Shader clock intrinsics
|
|
||||||
/// * Minor improvements and fixes
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 6.1 since version 6.0
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 6.1 includes the following updates:
|
|
||||||
/// * RDNA3 detection
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 6.0 since version 5.4.2
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 6.0 includes the following updates:
|
|
||||||
/// * DX12 ray tracing hit token for RDNA2 hardware.
|
|
||||||
/// * Shader intrinsic that exposes ReadLaneAt in DX12.
|
|
||||||
/// * Shader intrinsics that expose explicit float conversions in DX12.
|
|
||||||
/// * Refactored and revised API to minimize user error.
|
|
||||||
/// * Added agsGetVersionNumber.
|
|
||||||
/// * Detection for external GPUs.
|
|
||||||
/// * Detection of RDNA2 architecture.
|
|
||||||
/// * Grouped the more established intrinsics together into per year support.
|
|
||||||
/// * Function pointer typedefs for the API
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 5.4.2 since version 5.4.1
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 5.4.2 includes the following updates:
|
|
||||||
/// * sharedMemoryInBytes has been reinstated.
|
|
||||||
/// * Clock speed returned for APUs.
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 5.4.1 since version 5.4.0
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 5.4.1 includes the following updates:
|
|
||||||
/// * AsicFamily_Count to help with code maintenance.
|
|
||||||
/// * Visual Studio 2019 support.
|
|
||||||
/// * x86 support
|
|
||||||
/// * BaseInstance and BaseVertex intrinsics along with corresponding caps bits.
|
|
||||||
/// * GetWaveSize intrinsic along with corresponding caps bits.
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 5.4 since version 5.3
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 5.4 includes the following updates:
|
|
||||||
/// * A more detailed description of the GPU architecture, now including RDNA GPUs.
|
|
||||||
/// * Radeon 7 core and memory speeds returned.
|
|
||||||
/// * Draw index and Atomic U64 intrinsics for both DX11 and DX12.
|
|
||||||
///
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// What's new in AGS 5.3 since version 5.2
|
|
||||||
/// ---------------------------------------
|
|
||||||
/// AGS 5.3 includes the following updates:
|
|
||||||
/// * DX11 deferred context support for Multi Draw Indirect and UAV Overlap extensions.
|
|
||||||
/// * A Radeon Software Version helper to determine whether the installed driver meets your game's minimum driver version requirements.
|
|
||||||
/// * Freesync HDR Gamma 2.2 mode which uses a 1010102 swapchain and can be considered as an alternative to using the 64 bit swapchain required for Freesync HDR scRGB.
|
|
||||||
///
|
|
||||||
/// Using the AGS library
|
|
||||||
/// ---------------------
|
|
||||||
/// It is recommended to take a look at the source code for the samples that come with the AGS SDK:
|
|
||||||
/// * AGSSample
|
|
||||||
/// * CrossfireSample
|
|
||||||
/// * EyefinitySample
|
|
||||||
/// The AGSSample application is the simplest of the three examples and demonstrates the code required to initialize AGS and use it to query the GPU and Eyefinity state.
|
|
||||||
/// The CrossfireSample application demonstrates the use of the new API to transfer resources on GPUs in Crossfire mode. Lastly, the EyefinitySample application provides a more
|
|
||||||
/// extensive example of Eyefinity setup than the basic example provided in AGSSample.
|
|
||||||
/// There are other samples on Github that demonstrate the DirectX shader extensions, such as the Barycentrics11 and Barycentrics12 samples.
|
|
||||||
///
|
|
||||||
/// To add AGS support to an existing project, follow these steps:
|
|
||||||
/// * Link your project against the correct import library. Choose from either the 32 bit or 64 bit version.
|
|
||||||
/// * Copy the AGS dll into the same directory as your game executable.
|
|
||||||
/// * Include the amd_ags.h header file from your source code.
|
|
||||||
/// * Include the AGS hlsl files if you are using the shader intrinsics.
|
|
||||||
/// * Declare a pointer to an AGSContext and make this available for all subsequent calls to AGS.
|
|
||||||
/// * On game initialization, call \ref agsInitialize passing in the address of the context. On success, this function will return a valid context pointer.
|
|
||||||
///
|
|
||||||
/// Don't forget to cleanup AGS by calling \ref agsDeInitialize when the app exits, after the device has been destroyed.
|
|
||||||
|
|
||||||
#ifndef AMD_AGS_H
|
|
||||||
#define AMD_AGS_H
|
|
||||||
|
|
||||||
#define AMD_AGS_VERSION_MAJOR 6 ///< AGS major version
|
|
||||||
#define AMD_AGS_VERSION_MINOR 2 ///< AGS minor version
|
|
||||||
#define AMD_AGS_VERSION_PATCH 0 ///< AGS patch version
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \defgroup Defines AGS defines
|
|
||||||
/// @{
|
|
||||||
#if defined (AGS_GCC)
|
|
||||||
#define AMD_AGS_API
|
|
||||||
#else
|
|
||||||
#define AMD_AGS_API __declspec(dllexport) ///< AGS exported functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AGS_MAKE_VERSION( major, minor, patch ) ( ( major << 22 ) | ( minor << 12 ) | patch ) ///< Macro to create the app and engine versions for the fields in \ref AGSDX12ExtensionParams and \ref AGSDX11ExtensionParams and the Radeon Software Version
|
|
||||||
#define AGS_UNSPECIFIED_VERSION 0xFFFFAD00 ///< Use this to specify no version
|
|
||||||
#define AGS_CURRENT_VERSION AGS_MAKE_VERSION( AMD_AGS_VERSION_MAJOR, AMD_AGS_VERSION_MINOR, AMD_AGS_VERSION_PATCH ) ///< Macro to return the current AGS version as defined by the AGS header file
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \defgroup enums General enumerations
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/// The return codes
|
|
||||||
typedef enum AGSReturnCode
|
|
||||||
{
|
|
||||||
AGS_SUCCESS, ///< Successful function call
|
|
||||||
AGS_FAILURE, ///< Failed to complete call for some unspecified reason
|
|
||||||
AGS_INVALID_ARGS, ///< Invalid arguments into the function
|
|
||||||
AGS_OUT_OF_MEMORY, ///< Out of memory when allocating space internally
|
|
||||||
AGS_MISSING_D3D_DLL, ///< Returned when a D3D dll fails to load
|
|
||||||
AGS_LEGACY_DRIVER, ///< Returned if a feature is not present in the installed driver
|
|
||||||
AGS_NO_AMD_DRIVER_INSTALLED, ///< Returned if the AMD GPU driver does not appear to be installed
|
|
||||||
AGS_EXTENSION_NOT_SUPPORTED, ///< Returned if the driver does not support the requested driver extension
|
|
||||||
AGS_ADL_FAILURE, ///< Failure in ADL (the AMD Display Library)
|
|
||||||
AGS_DX_FAILURE, ///< Failure from DirectX runtime
|
|
||||||
AGS_D3DDEVICE_NOT_CREATED ///< Failure due to not creating the D3D device successfully via AGS.
|
|
||||||
} AGSReturnCode;
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
typedef struct AGSContext AGSContext; ///< All function calls in AGS require a pointer to a context. This is generated via \ref agsInitialize
|
|
||||||
|
|
||||||
/// The rectangle struct used by AGS.
|
|
||||||
typedef struct AGSRect
|
|
||||||
{
|
|
||||||
int offsetX; ///< Offset on X axis
|
|
||||||
int offsetY; ///< Offset on Y axis
|
|
||||||
int width; ///< Width of rectangle
|
|
||||||
int height; ///< Height of rectangle
|
|
||||||
} AGSRect;
|
|
||||||
|
|
||||||
/// The display info struct used to describe a display enumerated by AGS
|
|
||||||
typedef struct AGSDisplayInfo
|
|
||||||
{
|
|
||||||
char name[ 256 ]; ///< The name of the display
|
|
||||||
char displayDeviceName[ 32 ]; ///< The display device name, i.e. DISPLAY_DEVICE::DeviceName
|
|
||||||
|
|
||||||
unsigned int isPrimaryDisplay : 1; ///< Whether this display is marked as the primary display
|
|
||||||
unsigned int HDR10 : 1; ///< HDR10 is supported on this display
|
|
||||||
unsigned int dolbyVision : 1; ///< Dolby Vision is supported on this display
|
|
||||||
unsigned int freesync : 1; ///< Freesync is supported on this display
|
|
||||||
unsigned int freesyncHDR : 1; ///< Freesync HDR is supported on this display
|
|
||||||
unsigned int eyefinityInGroup : 1; ///< The display is part of the Eyefinity group
|
|
||||||
unsigned int eyefinityPreferredDisplay : 1; ///< The display is the preferred display in the Eyefinity group for displaying the UI
|
|
||||||
unsigned int eyefinityInPortraitMode : 1; ///< The display is in the Eyefinity group but in portrait mode
|
|
||||||
unsigned int reservedPadding : 24; ///< Reserved for future use
|
|
||||||
|
|
||||||
int maxResolutionX; ///< The maximum supported resolution of the unrotated display
|
|
||||||
int maxResolutionY; ///< The maximum supported resolution of the unrotated display
|
|
||||||
float maxRefreshRate; ///< The maximum supported refresh rate of the display
|
|
||||||
|
|
||||||
AGSRect currentResolution; ///< The current resolution and position in the desktop, ignoring Eyefinity bezel compensation
|
|
||||||
AGSRect visibleResolution; ///< The visible resolution and position. When Eyefinity bezel compensation is enabled this will
|
|
||||||
///< be the sub region in the Eyefinity single large surface (SLS)
|
|
||||||
float currentRefreshRate; ///< The current refresh rate
|
|
||||||
|
|
||||||
int eyefinityGridCoordX; ///< The X coordinate in the Eyefinity grid. -1 if not in an Eyefinity group
|
|
||||||
int eyefinityGridCoordY; ///< The Y coordinate in the Eyefinity grid. -1 if not in an Eyefinity group
|
|
||||||
|
|
||||||
double chromaticityRedX; ///< Red display primary X coord
|
|
||||||
double chromaticityRedY; ///< Red display primary Y coord
|
|
||||||
|
|
||||||
double chromaticityGreenX; ///< Green display primary X coord
|
|
||||||
double chromaticityGreenY; ///< Green display primary Y coord
|
|
||||||
|
|
||||||
double chromaticityBlueX; ///< Blue display primary X coord
|
|
||||||
double chromaticityBlueY; ///< Blue display primary Y coord
|
|
||||||
|
|
||||||
double chromaticityWhitePointX; ///< White point X coord
|
|
||||||
double chromaticityWhitePointY; ///< White point Y coord
|
|
||||||
|
|
||||||
double screenDiffuseReflectance; ///< Percentage expressed between 0 - 1
|
|
||||||
double screenSpecularReflectance; ///< Percentage expressed between 0 - 1
|
|
||||||
|
|
||||||
double minLuminance; ///< The minimum luminance of the display in nits
|
|
||||||
double maxLuminance; ///< The maximum luminance of the display in nits
|
|
||||||
double avgLuminance; ///< The average luminance of the display in nits
|
|
||||||
|
|
||||||
int logicalDisplayIndex; ///< The internally used index of this display
|
|
||||||
int adlAdapterIndex; ///< The internally used ADL adapter index
|
|
||||||
int reserved; ///< reserved field
|
|
||||||
} AGSDisplayInfo;
|
|
||||||
|
|
||||||
/// The ASIC family
|
|
||||||
typedef enum AsicFamily
|
|
||||||
{
|
|
||||||
AsicFamily_Unknown, ///< Unknown architecture, potentially from another IHV. Check \ref AGSDeviceInfo::vendorId
|
|
||||||
AsicFamily_PreGCN, ///< Pre GCN architecture.
|
|
||||||
AsicFamily_GCN1, ///< AMD GCN 1 architecture: Oland, Cape Verde, Pitcairn & Tahiti.
|
|
||||||
AsicFamily_GCN2, ///< AMD GCN 2 architecture: Hawaii & Bonaire. This also includes APUs Kaveri and Carrizo.
|
|
||||||
AsicFamily_GCN3, ///< AMD GCN 3 architecture: Tonga & Fiji.
|
|
||||||
AsicFamily_GCN4, ///< AMD GCN 4 architecture: Polaris.
|
|
||||||
AsicFamily_Vega, ///< AMD Vega architecture, including Raven Ridge (ie AMD Ryzen CPU + AMD Vega GPU).
|
|
||||||
AsicFamily_RDNA, ///< AMD RDNA architecture
|
|
||||||
AsicFamily_RDNA2, ///< AMD RDNA2 architecture
|
|
||||||
AsicFamily_RDNA3, ///< AMD RDNA3 architecture
|
|
||||||
|
|
||||||
AsicFamily_Count ///< Number of enumerated ASIC families
|
|
||||||
} AsicFamily;
|
|
||||||
|
|
||||||
/// The device info struct used to describe a physical GPU enumerated by AGS
|
|
||||||
typedef struct AGSDeviceInfo
|
|
||||||
{
|
|
||||||
const char* adapterString; ///< The adapter name string
|
|
||||||
AsicFamily asicFamily; ///< Set to Unknown if not AMD hardware
|
|
||||||
unsigned int isAPU : 1; ///< Whether this device is an APU
|
|
||||||
unsigned int isPrimaryDevice : 1; ///< Whether this device is marked as the primary device
|
|
||||||
unsigned int isExternal :1; ///< Whether this device is a detachable, external device
|
|
||||||
unsigned int reservedPadding : 29; ///< Reserved for future use
|
|
||||||
|
|
||||||
int vendorId; ///< The vendor id
|
|
||||||
int deviceId; ///< The device id
|
|
||||||
int revisionId; ///< The revision id
|
|
||||||
|
|
||||||
int numCUs; ///< Number of compute units
|
|
||||||
int numWGPs; ///< Number of RDNA Work Group Processors. Only valid if ASIC is RDNA onwards.
|
|
||||||
|
|
||||||
int numROPs; ///< Number of ROPs
|
|
||||||
int coreClock; ///< Core clock speed at 100% power in MHz
|
|
||||||
int memoryClock; ///< Memory clock speed at 100% power in MHz
|
|
||||||
int memoryBandwidth; ///< Memory bandwidth in MB/s
|
|
||||||
float teraFlops; ///< Teraflops of GPU. Zero if not GCN onwards. Calculated from iCoreClock * iNumCUs * 64 Pixels/clk * 2 instructions/MAD
|
|
||||||
|
|
||||||
unsigned long long localMemoryInBytes; ///< The size of local memory in bytes. 0 for non AMD hardware.
|
|
||||||
unsigned long long sharedMemoryInBytes; ///< The size of system memory available to the GPU in bytes. It is important to factor this into your VRAM budget for APUs
|
|
||||||
///< as the reported local memory will only be a small fraction of the total memory available to the GPU.
|
|
||||||
|
|
||||||
int numDisplays; ///< The number of active displays found to be attached to this adapter.
|
|
||||||
AGSDisplayInfo* displays; ///< List of displays allocated by AGS to be numDisplays in length.
|
|
||||||
|
|
||||||
int eyefinityEnabled; ///< Indicates if Eyefinity is active
|
|
||||||
int eyefinityGridWidth; ///< Contains width of the multi-monitor grid that makes up the Eyefinity Single Large Surface.
|
|
||||||
int eyefinityGridHeight; ///< Contains height of the multi-monitor grid that makes up the Eyefinity Single Large Surface.
|
|
||||||
int eyefinityResolutionX; ///< Contains width in pixels of the multi-monitor Single Large Surface.
|
|
||||||
int eyefinityResolutionY; ///< Contains height in pixels of the multi-monitor Single Large Surface.
|
|
||||||
int eyefinityBezelCompensated; ///< Indicates if bezel compensation is used for the current SLS display area. 1 if enabled, and 0 if disabled.
|
|
||||||
|
|
||||||
int adlAdapterIndex; ///< Internally used index into the ADL list of adapters
|
|
||||||
int reserved; ///< reserved field
|
|
||||||
} AGSDeviceInfo;
|
|
||||||
|
|
||||||
/// \defgroup general General API functions
|
|
||||||
/// API for initialization, cleanup, HDR display modes and Crossfire GPU count
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
typedef void* (__stdcall *AGS_ALLOC_CALLBACK)( size_t allocationSize ); ///< AGS user defined allocation prototype
|
|
||||||
typedef void (__stdcall *AGS_FREE_CALLBACK)( void* allocationPtr ); ///< AGS user defined free prototype
|
|
||||||
|
|
||||||
/// The configuration options that can be passed in to \ref agsInitialize
|
|
||||||
typedef struct AGSConfiguration
|
|
||||||
{
|
|
||||||
AGS_ALLOC_CALLBACK allocCallback; ///< Optional memory allocation callback. If not supplied, malloc() is used
|
|
||||||
AGS_FREE_CALLBACK freeCallback; ///< Optional memory freeing callback. If not supplied, free() is used
|
|
||||||
} AGSConfiguration;
|
|
||||||
|
|
||||||
/// The top level GPU information returned from \ref agsInitialize
|
|
||||||
typedef struct AGSGPUInfo
|
|
||||||
{
|
|
||||||
const char* driverVersion; ///< The AMD driver package version
|
|
||||||
const char* radeonSoftwareVersion; ///< The Radeon Software Version
|
|
||||||
|
|
||||||
int numDevices; ///< Number of GPUs in the system
|
|
||||||
AGSDeviceInfo* devices; ///< List of GPUs in the system
|
|
||||||
} AGSGPUInfo;
|
|
||||||
|
|
||||||
/// The struct to specify the display settings to the driver.
|
|
||||||
typedef struct AGSDisplaySettings AGSDisplaySettings;
|
|
||||||
|
|
||||||
|
|
||||||
/// The result returned from \ref agsCheckDriverVersion
|
|
||||||
typedef enum AGSDriverVersionResult
|
|
||||||
{
|
|
||||||
AGS_SOFTWAREVERSIONCHECK_OK, ///< The reported Radeon Software Version is newer or the same as the required version
|
|
||||||
AGS_SOFTWAREVERSIONCHECK_OLDER, ///< The reported Radeon Software Version is older than the required version
|
|
||||||
AGS_SOFTWAREVERSIONCHECK_UNDEFINED ///< The check could not determine as result. This could be because it is a private or custom driver or just invalid arguments.
|
|
||||||
} AGSDriverVersionResult;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Helper function to check the installed software version against the required software version.
|
|
||||||
///
|
|
||||||
/// \param [in] radeonSoftwareVersionReported The Radeon Software Version returned from \ref AGSGPUInfo::radeonSoftwareVersion.
|
|
||||||
/// \param [in] radeonSoftwareVersionRequired The Radeon Software Version to check against. This is specificed using \ref AGS_MAKE_VERSION.
|
|
||||||
/// \return The result of the check.
|
|
||||||
///
|
|
||||||
AMD_AGS_API AGSDriverVersionResult agsCheckDriverVersion( const char* radeonSoftwareVersionReported, unsigned int radeonSoftwareVersionRequired );
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Function to return the AGS version number.
|
|
||||||
///
|
|
||||||
/// \return The version number made using AGS_MAKE_VERSION( AMD_AGS_VERSION_MAJOR, AMD_AGS_VERSION_MINOR, AMD_AGS_VERSION_PATCH ).
|
|
||||||
///
|
|
||||||
AMD_AGS_API int agsGetVersionNumber();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Function used to initialize the AGS library.
|
|
||||||
/// agsVersion must be specified as AGS_CURRENT_VERSION or the call will return \ref AGS_INVALID_ARGS.
|
|
||||||
/// Must be called prior to any of the subsequent AGS API calls.
|
|
||||||
/// Must be called prior to ID3D11Device or ID3D12Device creation.
|
|
||||||
/// \note The caller of this function should handle the possibility of the call failing in the cases below. One option is to do a vendor id check and only call \ref agsInitialize if there is an AMD GPU present.
|
|
||||||
/// \note This function will fail with \ref AGS_NO_AMD_DRIVER_INSTALLED if there is no AMD driver found on the system.
|
|
||||||
/// \note This function will fail with \ref AGS_LEGACY_DRIVER in Catalyst versions before 12.20.
|
|
||||||
///
|
|
||||||
/// \param [in] agsVersion The API version specified using the \ref AGS_CURRENT_VERSION macro. If this does not match the version in the binary this initialization call will fail.
|
|
||||||
/// \param [in] config Optional pointer to a AGSConfiguration struct to override the default library configuration.
|
|
||||||
/// \param [out] context Address of a pointer to a context. This function allocates a context on the heap which is then required for all subsequent API calls.
|
|
||||||
/// \param [out] gpuInfo Optional pointer to a AGSGPUInfo struct which will get filled in for all the GPUs in the system.
|
|
||||||
///
|
|
||||||
AMD_AGS_API AGSReturnCode agsInitialize( int agsVersion, const AGSConfiguration* config, AGSContext** context, AGSGPUInfo* gpuInfo );
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Function used to clean up the AGS library.
|
|
||||||
///
|
|
||||||
/// \param [in] context Pointer to a context. This function will deallocate the context from the heap.
|
|
||||||
///
|
|
||||||
AMD_AGS_API AGSReturnCode agsDeInitialize( AGSContext* context );
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Function used to set a specific display into HDR mode
|
|
||||||
/// \note Setting all of the values apart from color space and transfer function to zero will cause the display to use defaults.
|
|
||||||
/// \note Call this function after each mode change (switch to fullscreen, any change in swapchain etc).
|
|
||||||
/// \note HDR10 PQ mode requires a 1010102 swapchain.
|
|
||||||
/// \note HDR10 scRGB mode requires an FP16 swapchain.
|
|
||||||
/// \note Freesync HDR scRGB mode requires an FP16 swapchain.
|
|
||||||
/// \note Freesync HDR Gamma 2.2 mode requires a 1010102 swapchain.
|
|
||||||
/// \note Dolby Vision requires a 8888 UNORM swapchain.
|
|
||||||
///
|
|
||||||
/// \param [in] context Pointer to a context. This is generated by \ref agsInitialize
|
|
||||||
/// \param [in] deviceIndex The index of the device listed in \ref AGSGPUInfo::devices.
|
|
||||||
/// \param [in] displayIndex The index of the display listed in \ref AGSDeviceInfo::displays.
|
|
||||||
/// \param [in] settings Pointer to the display settings to use.
|
|
||||||
///
|
|
||||||
AMD_AGS_API AGSReturnCode agsSetDisplayMode( AGSContext* context, int deviceIndex, int displayIndex, const AGSDisplaySettings* settings );
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // AMD_AGS_H
|
|
||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"home": "https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK",
|
|
||||||
"license": "MIT (embeded in source)",
|
|
||||||
"version": "AGS v6.2.0",
|
|
||||||
"author": "Advanced Micro Devices, Inc",
|
|
||||||
"modified": "CarterLi"
|
|
||||||
}
|
|
||||||
+2596
File diff suppressed because it is too large
Load Diff
+46
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// MIT LICENSE:
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
/// \file adl_sdk.h
|
||||||
|
/// \brief Contains the definition of the Memory Allocation Callback.\n <b>Included in ADL SDK</b>
|
||||||
|
///
|
||||||
|
/// \n\n
|
||||||
|
/// This file contains the definition of the Memory Allocation Callback.\n
|
||||||
|
/// It also includes definitions of the respective structures and constants.\n
|
||||||
|
/// <b> This is the only header file to be included in a C/C++ project using ADL </b>
|
||||||
|
|
||||||
|
#ifndef ADL_SDK_H_
|
||||||
|
#define ADL_SDK_H_
|
||||||
|
|
||||||
|
#include "adl_structures.h"
|
||||||
|
|
||||||
|
#if defined (LINUX)
|
||||||
|
#define __stdcall
|
||||||
|
#endif /* (LINUX) */
|
||||||
|
|
||||||
|
/// Memory Allocation Call back
|
||||||
|
typedef void* ( __stdcall *ADL_MAIN_MALLOC_CALLBACK )( int );
|
||||||
|
|
||||||
|
#define ADL_SDK_MAJOR_VERSION 17
|
||||||
|
#define ADL_SDK_MINOR_VERSION 1
|
||||||
|
|
||||||
|
#endif /* ADL_SDK_H_ */
|
||||||
+4289
File diff suppressed because it is too large
Load Diff
+6
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"home": "https://github.com/GPUOpen-LibrariesAndSDKs/display-library",
|
||||||
|
"license": "MIT (embeded in source)",
|
||||||
|
"version": "ADL SDK 17.1",
|
||||||
|
"author": "Advanced Micro Devices, Inc"
|
||||||
|
}
|
||||||
+3
-3
@@ -227,15 +227,15 @@ void ffListFeatures(void)
|
|||||||
#if FF_HAVE_GLX
|
#if FF_HAVE_GLX
|
||||||
"glx\n"
|
"glx\n"
|
||||||
#endif
|
#endif
|
||||||
#if FF_HAVE_OSMESA
|
|
||||||
"osmesa\n"
|
|
||||||
#endif
|
|
||||||
#if FF_HAVE_OPENCL
|
#if FF_HAVE_OPENCL
|
||||||
"opencl\n"
|
"opencl\n"
|
||||||
#endif
|
#endif
|
||||||
#if FF_HAVE_FREETYPE
|
#if FF_HAVE_FREETYPE
|
||||||
"freetype\n"
|
"freetype\n"
|
||||||
#endif
|
#endif
|
||||||
|
#if FF_HAVE_PCIACCESS
|
||||||
|
"libpciaccess\n"
|
||||||
|
#endif
|
||||||
#if FF_HAVE_PULSE
|
#if FF_HAVE_PULSE
|
||||||
"libpulse\n"
|
"libpulse\n"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if __APPLE__ // #1395
|
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
if(stat(path, &fileStat) != 0)
|
if(stat(path, &fileStat) != 0)
|
||||||
return false;
|
return false;
|
||||||
@@ -131,24 +130,6 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
|
|||||||
|
|
||||||
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
size_t len = strlen(path);
|
|
||||||
assert(len < PATH_MAX);
|
|
||||||
if (len == 0) return false;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
if (path[len - 1] != '/')
|
|
||||||
{
|
|
||||||
char buf[PATH_MAX + 1];
|
|
||||||
memcpy(buf, path, len);
|
|
||||||
buf[len] = '/';
|
|
||||||
buf[len + 1] = 0;
|
|
||||||
ret = access(buf, F_OK);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = access(path, F_OK);
|
|
||||||
return pathType == FF_PATHTYPE_DIRECTORY ? ret == 0 : ret == -1 && errno == ENOTDIR;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -256,6 +256,11 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
|||||||
|
|
||||||
bool ffSuppressIO(bool suppress)
|
bool ffSuppressIO(bool suppress)
|
||||||
{
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (instance.config.display.debugMode)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
static int origOut = -1;
|
static int origOut = -1;
|
||||||
static int origErr = -1;
|
static int origErr = -1;
|
||||||
|
|||||||
@@ -159,6 +159,11 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
|||||||
|
|
||||||
bool ffSuppressIO(bool suppress)
|
bool ffSuppressIO(bool suppress)
|
||||||
{
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (instance.config.display.debugMode)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
|
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
|
||||||
static HANDLE hOrigErr = INVALID_HANDLE_VALUE;
|
static HANDLE hOrigErr = INVALID_HANDLE_VALUE;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#else
|
#else
|
||||||
#define IF_NAMESIZE 16
|
#define IF_NAMESIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex);
|
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "netif.h"
|
#include "netif.h"
|
||||||
|
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
|
#include "util/mallocHelper.h"
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
@@ -8,13 +9,17 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#if defined(__OpenBSD__) || defined(__DragonFly__)
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
|
#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t))
|
# define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t))
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||||
#elif defined(__OpenBSD__)
|
#elif defined(__OpenBSD__)
|
||||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||||
@@ -47,6 +52,39 @@ get_rt_address(struct rt_msghdr *rtm, int desired)
|
|||||||
|
|
||||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||||
{
|
{
|
||||||
|
#if defined(__OpenBSD__) || defined(__DragonFly__)
|
||||||
|
int mib[6] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY};
|
||||||
|
size_t needed;
|
||||||
|
|
||||||
|
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FF_AUTO_FREE char* buf = malloc(needed);
|
||||||
|
|
||||||
|
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char* lim = buf + needed;
|
||||||
|
struct rt_msghdr* rtm;
|
||||||
|
for (char* next = buf; next < lim; next += rtm->rtm_msglen)
|
||||||
|
{
|
||||||
|
rtm = (struct rt_msghdr *)next;
|
||||||
|
struct sockaddr* sa = (struct sockaddr *)(rtm + 1);
|
||||||
|
|
||||||
|
if ((rtm->rtm_flags & RTF_GATEWAY) && (sa->sa_family == AF_INET))
|
||||||
|
{
|
||||||
|
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP);
|
||||||
|
if (sdl->sdl_family == AF_LINK)
|
||||||
|
{
|
||||||
|
assert(sdl->sdl_nlen <= IF_NAMESIZE);
|
||||||
|
memcpy(iface, sdl->sdl_data, sdl->sdl_nlen);
|
||||||
|
iface[sdl->sdl_nlen] = '\0';
|
||||||
|
*ifIndex = sdl->sdl_index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
|
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
|
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
|
||||||
@@ -106,5 +144,7 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
int size = config.ifc_value;
|
int size = config.ifc_value;
|
||||||
if (size == 0)
|
if (size <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FF_AUTO_FREE void *buffer = malloc(size);
|
FF_AUTO_FREE void *buffer = malloc((size_t) size);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#define FF_STR_INDIR(x) #x
|
#define FF_STR_INDIR(x) #x
|
||||||
#define FF_STR(x) FF_STR_INDIR(x)
|
#define FF_STR(x) FF_STR_INDIR(x)
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
static bool getDefaultRouteIPv4(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||||
{
|
{
|
||||||
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r");
|
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r");
|
||||||
if (!netRoute) return false;
|
if (!netRoute) return false;
|
||||||
@@ -15,12 +15,38 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
|||||||
// skip first line
|
// skip first line
|
||||||
FF_UNUSED(fscanf(netRoute, "%*[^\n]\n"));
|
FF_UNUSED(fscanf(netRoute, "%*[^\n]\n"));
|
||||||
|
|
||||||
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu,
|
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu, ...
|
||||||
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2)
|
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2)
|
||||||
{
|
{
|
||||||
if (destination != 0) continue;
|
if (destination != 0) continue;
|
||||||
*ifIndex = if_nametoindex(iface);
|
*ifIndex = if_nametoindex(iface);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
iface[0] = '\0';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool getDefaultRouteIPv6(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||||
|
{
|
||||||
|
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/ipv6_route", "r");
|
||||||
|
if (!netRoute) return false;
|
||||||
|
|
||||||
|
uint32_t prefixLen;
|
||||||
|
//destination, dest_prefix_len, source, src_prefix_len, next hop, metric, ref counter, use counter, flags, iface
|
||||||
|
while (fscanf(netRoute, "%*s %x %*s %*s %*s %*s %*s %*s %*s %" FF_STR(IF_NAMESIZE) "s", &prefixLen, iface) == 2)
|
||||||
|
{
|
||||||
|
if (prefixLen != 0) continue;
|
||||||
|
*ifIndex = if_nametoindex(iface);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
iface[0] = '\0';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||||
|
{
|
||||||
|
if (getDefaultRouteIPv4(iface, ifIndex))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return getDefaultRouteIPv6(iface, ifIndex);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,27 +1,36 @@
|
|||||||
#include "netif.h"
|
#include "netif.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "util/mallocHelper.h"
|
||||||
|
|
||||||
|
#include <ws2tcpip.h> // AF_INET6, IN6_IS_ADDR_UNSPECIFIED
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
|
||||||
bool ffNetifGetDefaultRouteImpl(FF_MAYBE_UNUSED char* iface/* unsupported */, uint32_t* ifIndex)
|
bool ffNetifGetDefaultRouteImpl(FF_MAYBE_UNUSED char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||||
{
|
{
|
||||||
ULONG size = 0;
|
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
|
||||||
if (GetIpForwardTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER)
|
DWORD result = GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable);
|
||||||
|
|
||||||
|
if (result != NO_ERROR)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FF_AUTO_FREE MIB_IPFORWARDTABLE* pIpForwardTable = (MIB_IPFORWARDTABLE*) malloc(size);
|
bool foundDefault = false;
|
||||||
if (GetIpForwardTable(pIpForwardTable, &size, TRUE) != ERROR_SUCCESS)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pIpForwardTable->dwNumEntries; ++i)
|
for (ULONG i = 0; i < pIpForwardTable->NumEntries; ++i)
|
||||||
{
|
{
|
||||||
MIB_IPFORWARDROW* ipForwardRow = &pIpForwardTable->table[i];
|
MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
|
||||||
if (ipForwardRow->dwForwardDest == 0 && ipForwardRow->dwForwardMask == 0)
|
|
||||||
|
if ((row->DestinationPrefix.PrefixLength == 0) &&
|
||||||
|
((row->DestinationPrefix.Prefix.Ipv4.sin_family == AF_INET &&
|
||||||
|
row->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr == 0) ||
|
||||||
|
(row->DestinationPrefix.Prefix.Ipv6.sin6_family == AF_INET6 &&
|
||||||
|
IN6_IS_ADDR_UNSPECIFIED(&row->DestinationPrefix.Prefix.Ipv6.sin6_addr))))
|
||||||
{
|
{
|
||||||
*ifIndex = ipForwardRow->dwForwardIfIndex;
|
*ifIndex = row->InterfaceIndex;
|
||||||
|
foundDefault = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
FreeMibTable(pIpForwardTable);
|
||||||
|
|
||||||
|
return foundDefault;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,16 @@
|
|||||||
#include <minwindef.h>
|
#include <minwindef.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct addrinfo;
|
||||||
|
|
||||||
typedef struct FFNetworkingState {
|
typedef struct FFNetworkingState {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
uintptr_t sockfd;
|
uintptr_t sockfd;
|
||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
#else
|
#else
|
||||||
int sockfd;
|
int sockfd;
|
||||||
FFstrbuf host;
|
|
||||||
FFstrbuf command;
|
FFstrbuf command;
|
||||||
|
struct addrinfo* addr;
|
||||||
|
|
||||||
#ifdef FF_HAVE_THREADS
|
#ifdef FF_HAVE_THREADS
|
||||||
FFThreadType thread;
|
FFThreadType thread;
|
||||||
@@ -23,7 +25,14 @@ typedef struct FFNetworkingState {
|
|||||||
|
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
bool ipv6;
|
bool ipv6;
|
||||||
|
bool compression; // if true, HTTP content compression will be enabled if supported
|
||||||
|
bool tfo; // if true, TCP Fast Open will be attempted first, and fallback to traditional connection if it fails
|
||||||
} FFNetworkingState;
|
} FFNetworkingState;
|
||||||
|
|
||||||
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer);
|
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer);
|
||||||
|
|
||||||
|
#ifdef FF_HAVE_ZLIB
|
||||||
|
const char* ffNetworkingLoadZlibLibrary(void);
|
||||||
|
bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd);
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
#include "fastfetch.h"
|
||||||
|
#include "common/library.h"
|
||||||
|
#include "common/networking/networking.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
#include "util/debug.h"
|
||||||
|
|
||||||
|
#ifdef FF_HAVE_ZLIB
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
struct FFZlibLibrary
|
||||||
|
{
|
||||||
|
FF_LIBRARY_SYMBOL(inflateInit2_)
|
||||||
|
FF_LIBRARY_SYMBOL(inflate)
|
||||||
|
FF_LIBRARY_SYMBOL(inflateEnd)
|
||||||
|
FF_LIBRARY_SYMBOL(inflateGetHeader)
|
||||||
|
|
||||||
|
bool inited;
|
||||||
|
} zlibData;
|
||||||
|
|
||||||
|
const char* ffNetworkingLoadZlibLibrary(void)
|
||||||
|
{
|
||||||
|
if (!zlibData.inited)
|
||||||
|
{
|
||||||
|
zlibData.inited = true;
|
||||||
|
FF_LIBRARY_LOAD(zlib, "dlopen libz failed",
|
||||||
|
#ifdef _WIN32
|
||||||
|
"zlib1"
|
||||||
|
#else
|
||||||
|
"libz"
|
||||||
|
#endif
|
||||||
|
FF_LIBRARY_EXTENSION, 2)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateInit2_)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflate)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateEnd)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(zlib, zlibData, inflateGetHeader)
|
||||||
|
zlib = NULL; // don't auto dlclose
|
||||||
|
}
|
||||||
|
return zlibData.ffinflateEnd == NULL ? "Failed to load libz" : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to pre-read gzip header to determine uncompressed size
|
||||||
|
static uint32_t guessGzipOutputSize(const void* data, uint32_t dataSize)
|
||||||
|
{
|
||||||
|
// gzip file format: http://www.zlib.org/rfc-gzip.html
|
||||||
|
if (dataSize < 10 || ((const uint8_t*)data)[0] != 0x1f || ((const uint8_t*)data)[1] != 0x8b)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Uncompressed size in gzip format is stored in the last 4 bytes, but only valid if data is less than 4GB
|
||||||
|
if (dataSize > 18) {
|
||||||
|
// Get ISIZE value from the end of file (little endian)
|
||||||
|
const uint8_t* tail = (const uint8_t*)data + dataSize - 4;
|
||||||
|
uint32_t uncompressedSize = (uint32_t) tail[0] | ((uint32_t) tail[1] << 8u) | ((uint32_t) tail[2] << 16u) | ((uint32_t) tail[3] << 24u);
|
||||||
|
|
||||||
|
// For valid gzip files, this value is the length of the uncompressed data modulo 2^32
|
||||||
|
if (uncompressedSize > 0) {
|
||||||
|
FF_DEBUG("Read uncompressed size from GZIP trailer: %u bytes", uncompressedSize);
|
||||||
|
// Add some margin to the estimated size for safety
|
||||||
|
return uncompressedSize + 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If unable to get size from trailer or size is 0, use estimated value
|
||||||
|
// Typically, text data compression ratio is between 3-5x, we use the larger value
|
||||||
|
uint32_t estimatedSize = dataSize * 5;
|
||||||
|
FF_DEBUG("Unable to read exact uncompressed size, estimated as 5x of compressed data: %u bytes", estimatedSize);
|
||||||
|
return estimatedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress gzip content
|
||||||
|
bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd)
|
||||||
|
{
|
||||||
|
// Calculate header size
|
||||||
|
uint32_t headerSize = (uint32_t) (headerEnd - buffer->chars);
|
||||||
|
|
||||||
|
*headerEnd = '\0'; // Replace delimiter with null character for easier processing
|
||||||
|
// Ensure Content-Encoding is in response headers, not in response body
|
||||||
|
bool hasGzip = strcasestr(buffer->chars, "\nContent-Encoding: gzip") != NULL;
|
||||||
|
*headerEnd = '\r'; // Restore delimiter
|
||||||
|
|
||||||
|
if (!hasGzip) {
|
||||||
|
FF_DEBUG("No gzip compressed content detected, skipping decompression");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_DEBUG("Gzip compressed content detected, preparing for decompression");
|
||||||
|
|
||||||
|
const char* bodyStart = headerEnd + 4; // Skip delimiter
|
||||||
|
|
||||||
|
// Calculate compressed content size
|
||||||
|
uint32_t compressedSize = buffer->length - headerSize - 4;
|
||||||
|
|
||||||
|
if (compressedSize <= 0) {
|
||||||
|
// No content to decompress
|
||||||
|
FF_DEBUG("Compressed content size is 0, skipping decompression");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if content is actually in gzip format (gzip header magic is 0x1f 0x8b)
|
||||||
|
if (compressedSize < 2 || (uint8_t)bodyStart[0] != 0x1f || (uint8_t)bodyStart[1] != 0x8b) {
|
||||||
|
FF_DEBUG("Content is not valid gzip format, skipping decompression");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Predict uncompressed size
|
||||||
|
uint32_t estimatedSize = guessGzipOutputSize(bodyStart, compressedSize);
|
||||||
|
|
||||||
|
// Create decompression buffer with estimated size
|
||||||
|
FF_STRBUF_AUTO_DESTROY decompressedBuffer = ffStrbufCreateA(estimatedSize > 0 ? estimatedSize : compressedSize * 5);
|
||||||
|
FF_DEBUG("Created decompression buffer: %u bytes", decompressedBuffer.allocated);
|
||||||
|
|
||||||
|
// Initialize decompression
|
||||||
|
z_stream zs = {
|
||||||
|
.zalloc = Z_NULL,
|
||||||
|
.zfree = Z_NULL,
|
||||||
|
.opaque = Z_NULL,
|
||||||
|
.avail_in = (uInt)compressedSize,
|
||||||
|
.next_in = (Bytef*)bodyStart,
|
||||||
|
.avail_out = (uInt)ffStrbufGetFree(&decompressedBuffer),
|
||||||
|
.next_out = (Bytef*)decompressedBuffer.chars,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize decompression engine
|
||||||
|
if (zlibData.ffinflateInit2_(&zs, 16 + MAX_WBITS, ZLIB_VERSION, (int)sizeof(z_stream)) != Z_OK) {
|
||||||
|
FF_DEBUG("Failed to initialize decompression engine");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uInt availableOut = zs.avail_out;
|
||||||
|
|
||||||
|
// Perform decompression
|
||||||
|
int result = zlibData.ffinflate(&zs, Z_FINISH);
|
||||||
|
|
||||||
|
// If output buffer is insufficient, try to extend buffer
|
||||||
|
while (result == Z_BUF_ERROR || (result != Z_STREAM_END && zs.avail_out == 0))
|
||||||
|
{
|
||||||
|
FF_DEBUG("Output buffer insufficient, trying to extend");
|
||||||
|
|
||||||
|
// Save already decompressed data amount
|
||||||
|
uint32_t alreadyDecompressed = (uint32_t)(availableOut - zs.avail_out);
|
||||||
|
decompressedBuffer.length += alreadyDecompressed;
|
||||||
|
decompressedBuffer.chars[decompressedBuffer.length] = '\0'; // Ensure null-terminated string
|
||||||
|
|
||||||
|
ffStrbufEnsureFree(&decompressedBuffer, decompressedBuffer.length / 2);
|
||||||
|
|
||||||
|
// Set output parameters to point to new buffer
|
||||||
|
zs.avail_out = (uInt)ffStrbufGetFree(&decompressedBuffer);
|
||||||
|
zs.next_out = (Bytef*)(decompressedBuffer.chars + decompressedBuffer.length);
|
||||||
|
availableOut = zs.avail_out;
|
||||||
|
|
||||||
|
// Decompress again
|
||||||
|
result = zlibData.ffinflate(&zs, Z_FINISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
zlibData.ffinflateEnd(&zs);
|
||||||
|
|
||||||
|
// Calculate decompressed size
|
||||||
|
uint32_t decompressedSize = (uint32_t)(availableOut - zs.avail_out);
|
||||||
|
decompressedBuffer.length += decompressedSize;
|
||||||
|
decompressedBuffer.chars[decompressedSize] = '\0'; // Ensure null-terminated string
|
||||||
|
FF_DEBUG("Successfully decompressed %u bytes compressed data to %u bytes", compressedSize, decompressedBuffer.length);
|
||||||
|
|
||||||
|
// Modify Content-Length header and remove Content-Encoding header
|
||||||
|
FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedSize + 64);
|
||||||
|
|
||||||
|
char* line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
while (ffStrbufGetline(&line, &len, buffer))
|
||||||
|
{
|
||||||
|
if (ffStrStartsWithIgnCase(line, "Content-Encoding:"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ffStrStartsWithIgnCase(line, "Content-Length:"))
|
||||||
|
{
|
||||||
|
ffStrbufAppendF(&newBuffer, "Content-Length: %u\r\n", decompressedSize);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (line[0] == '\r')
|
||||||
|
{
|
||||||
|
ffStrbufAppendS(&newBuffer, "\r\n");
|
||||||
|
ffStrbufGetlineRestore(&line, &len, buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendS(&newBuffer, line);
|
||||||
|
ffStrbufAppendC(&newBuffer, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppend(&newBuffer, &decompressedBuffer);
|
||||||
|
ffStrbufDestroy(buffer);
|
||||||
|
ffStrbufInitMove(buffer, &newBuffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // FF_HAVE_ZLIB
|
||||||
@@ -0,0 +1,500 @@
|
|||||||
|
#include "fastfetch.h"
|
||||||
|
#include "common/networking/networking.h"
|
||||||
|
#include "common/time.h"
|
||||||
|
#include "common/library.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
#include "util/mallocHelper.h"
|
||||||
|
#include "util/debug.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h> // For FreeBSD
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
static const char* tryNonThreadingFastPath(FFNetworkingState* state)
|
||||||
|
{
|
||||||
|
#if defined(TCP_FASTOPEN) || __APPLE__
|
||||||
|
|
||||||
|
if (!state->tfo)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
// Linux doesn't support sendto() on unconnected sockets
|
||||||
|
FF_DEBUG("TCP Fast Open disabled, skipping");
|
||||||
|
return "TCP Fast Open disabled";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FF_DEBUG("Attempting to use TCP Fast Open to connect");
|
||||||
|
|
||||||
|
#ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed
|
||||||
|
// Set TCP Fast Open
|
||||||
|
#ifdef __linux__
|
||||||
|
int flag = 5; // the queue length of pending packets
|
||||||
|
#else
|
||||||
|
int flag = 1; // enable TCP Fast Open
|
||||||
|
#endif
|
||||||
|
if (setsockopt(state->sockfd, IPPROTO_TCP,
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// https://github.com/rust-lang/libc/pull/3135
|
||||||
|
0x218 // TCP_FASTOPEN_FORCE_ENABLE
|
||||||
|
#else
|
||||||
|
TCP_FASTOPEN
|
||||||
|
#endif
|
||||||
|
, &flag, sizeof(flag)) != 0) {
|
||||||
|
FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", strerror(errno));
|
||||||
|
return "setsockopt(TCP_FASTOPEN) failed";
|
||||||
|
} else {
|
||||||
|
#ifdef __linux__
|
||||||
|
FF_DEBUG("Successfully set TCP_FASTOPEN option, queue length: %d", flag);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
FF_DEBUG("Successfully set TCP_FASTOPEN_FORCE_ENABLE option");
|
||||||
|
#else
|
||||||
|
FF_DEBUG("Successfully set TCP_FASTOPEN option");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
FF_DEBUG("Using sendto() + MSG_DONTWAIT to send %u bytes of data", state->command.length);
|
||||||
|
ssize_t sent = sendto(state->sockfd,
|
||||||
|
state->command.chars,
|
||||||
|
state->command.length,
|
||||||
|
#ifdef MSG_FASTOPEN
|
||||||
|
MSG_FASTOPEN |
|
||||||
|
#endif
|
||||||
|
#ifdef MSG_NOSIGNAL
|
||||||
|
MSG_NOSIGNAL |
|
||||||
|
#endif
|
||||||
|
MSG_DONTWAIT,
|
||||||
|
state->addr->ai_addr,
|
||||||
|
state->addr->ai_addrlen);
|
||||||
|
#else
|
||||||
|
if (fcntl(state->sockfd, F_SETFL, O_NONBLOCK) == -1) {
|
||||||
|
FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno));
|
||||||
|
return "fcntl(F_SETFL) failed";
|
||||||
|
}
|
||||||
|
FF_DEBUG("Using connectx() to send %u bytes of data", state->command.length);
|
||||||
|
// Use connectx to establish connection and send data in one call
|
||||||
|
size_t sent;
|
||||||
|
if (connectx(state->sockfd,
|
||||||
|
&(sa_endpoints_t) {
|
||||||
|
.sae_dstaddr = state->addr->ai_addr,
|
||||||
|
.sae_dstaddrlen = state->addr->ai_addrlen,
|
||||||
|
},
|
||||||
|
SAE_ASSOCID_ANY, state->tfo ? CONNECT_DATA_IDEMPOTENT : 0,
|
||||||
|
&(struct iovec) {
|
||||||
|
.iov_base = state->command.chars,
|
||||||
|
.iov_len = state->command.length,
|
||||||
|
}, 1, &sent, NULL) != 0) sent = 0;
|
||||||
|
if (fcntl(state->sockfd, F_SETFL, 0) == -1) {
|
||||||
|
FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno));
|
||||||
|
return "fcntl(F_SETFL) failed";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (sent > 0 || (errno == EAGAIN || errno == EWOULDBLOCK
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// On macOS EINPROGRESS means the connection cannot be completed immediately
|
||||||
|
// On Linux, it means the TFO cookie is not available locally
|
||||||
|
|| errno == EINPROGRESS
|
||||||
|
#endif
|
||||||
|
))
|
||||||
|
{
|
||||||
|
FF_DEBUG(
|
||||||
|
#ifdef __APPLE__
|
||||||
|
"connectx()"
|
||||||
|
#else
|
||||||
|
"sendto()"
|
||||||
|
#endif
|
||||||
|
" %s (sent=%zd, errno=%d: %s)", errno == 0 ? "succeeded" : "was in progress",
|
||||||
|
sent, errno, strerror(errno));
|
||||||
|
freeaddrinfo(state->addr);
|
||||||
|
state->addr = NULL;
|
||||||
|
ffStrbufDestroy(&state->command);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_DEBUG(
|
||||||
|
#ifdef __APPLE__
|
||||||
|
"connectx()"
|
||||||
|
#else
|
||||||
|
"sendto()"
|
||||||
|
#endif
|
||||||
|
" failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
#ifdef __APPLE__
|
||||||
|
return "connectx() failed";
|
||||||
|
#else
|
||||||
|
return "sendto() failed";
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
FF_UNUSED(state);
|
||||||
|
return "TFO support is not available";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traditional connect and send function
|
||||||
|
static const char* connectAndSend(FFNetworkingState* state)
|
||||||
|
{
|
||||||
|
const char* ret = NULL;
|
||||||
|
FF_DEBUG("Using traditional connection method to connect");
|
||||||
|
|
||||||
|
FF_DEBUG("Attempting connect() to server...");
|
||||||
|
if(connect(state->sockfd, state->addr->ai_addr, state->addr->ai_addrlen) == -1)
|
||||||
|
{
|
||||||
|
FF_DEBUG("connect() failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
ret = "connect() failed";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
FF_DEBUG("connect() succeeded");
|
||||||
|
|
||||||
|
FF_DEBUG("Attempting to send %u bytes of data...", state->command.length);
|
||||||
|
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("send() failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
ret = "send() failed";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
FF_DEBUG("Data sent successfully");
|
||||||
|
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
error:
|
||||||
|
FF_DEBUG("Error occurred, closing socket");
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
FF_DEBUG("Releasing address info and other resources");
|
||||||
|
freeaddrinfo(state->addr);
|
||||||
|
state->addr = NULL;
|
||||||
|
ffStrbufDestroy(&state->command);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
||||||
|
|
||||||
|
// Parallel DNS resolution and socket creation
|
||||||
|
static const char* initNetworkingState(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Initializing network connection state: host=%s, path=%s", host, path);
|
||||||
|
|
||||||
|
// Initialize command and host information
|
||||||
|
ffStrbufInitA(&state->command, 64);
|
||||||
|
ffStrbufAppendS(&state->command, "GET ");
|
||||||
|
ffStrbufAppendS(&state->command, path);
|
||||||
|
ffStrbufAppendS(&state->command, " HTTP/1.0\nHost: ");
|
||||||
|
ffStrbufAppendS(&state->command, host);
|
||||||
|
ffStrbufAppendS(&state->command, "\r\n");
|
||||||
|
|
||||||
|
// Add extra optimized HTTP headers
|
||||||
|
ffStrbufAppendS(&state->command, "Connection: close\r\n"); // Explicitly tell the server we don't need to keep the connection
|
||||||
|
|
||||||
|
// If compression needs to be enabled
|
||||||
|
if (state->compression) {
|
||||||
|
FF_DEBUG("Enabling HTTP content compression");
|
||||||
|
ffStrbufAppendS(&state->command, "Accept-Encoding: gzip\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendS(&state->command, headers);
|
||||||
|
ffStrbufAppendS(&state->command, "\r\n");
|
||||||
|
|
||||||
|
#ifdef FF_HAVE_THREADS
|
||||||
|
state->thread = 0;
|
||||||
|
FF_DEBUG("Thread ID initialized to 0");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* ret = NULL;
|
||||||
|
|
||||||
|
struct addrinfo hints = {
|
||||||
|
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
||||||
|
.ai_socktype = SOCK_STREAM,
|
||||||
|
.ai_flags = AI_NUMERICSERV
|
||||||
|
};
|
||||||
|
|
||||||
|
FF_DEBUG("Resolving address: %s (%s)", host, state->ipv6 ? "IPv6" : "IPv4");
|
||||||
|
// Use AI_NUMERICSERV flag to indicate the service is a numeric port, reducing parsing time
|
||||||
|
|
||||||
|
if(getaddrinfo(host, "80", &hints, &state->addr) != 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("getaddrinfo() failed: %s", gai_strerror(errno));
|
||||||
|
ret = "getaddrinfo() failed";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
FF_DEBUG("Address resolution successful");
|
||||||
|
|
||||||
|
FF_DEBUG("Creating socket");
|
||||||
|
state->sockfd = socket(state->addr->ai_family, state->addr->ai_socktype, state->addr->ai_protocol);
|
||||||
|
if(state->sockfd == -1)
|
||||||
|
{
|
||||||
|
FF_DEBUG("socket() failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
ret = "socket() failed";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
FF_DEBUG("Socket creation successful: fd=%d", state->sockfd);
|
||||||
|
|
||||||
|
int flag = 1;
|
||||||
|
#ifdef TCP_NODELAY
|
||||||
|
// Disable Nagle's algorithm to reduce small packet transmission delay
|
||||||
|
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) != 0) {
|
||||||
|
FF_DEBUG("Failed to set TCP_NODELAY: %s", strerror(errno));
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Successfully disabled Nagle's algorithm");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TCP_QUICKACK
|
||||||
|
// Set TCP_QUICKACK option to avoid delayed acknowledgments
|
||||||
|
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(flag)) != 0) {
|
||||||
|
FF_DEBUG("Failed to set TCP_QUICKACK: %s", strerror(errno));
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Successfully enabled TCP quick acknowledgment");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (state->timeout > 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Setting connection timeout: %u ms", state->timeout);
|
||||||
|
FF_MAYBE_UNUSED uint32_t sec = state->timeout / 1000;
|
||||||
|
if (sec == 0) sec = 1;
|
||||||
|
|
||||||
|
#ifdef TCP_CONNECTIONTIMEOUT
|
||||||
|
FF_DEBUG("Using TCP_CONNECTIONTIMEOUT: %u seconds", sec);
|
||||||
|
setsockopt(state->sockfd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &sec, sizeof(sec));
|
||||||
|
#elif defined(TCP_KEEPINIT)
|
||||||
|
FF_DEBUG("Using TCP_KEEPINIT: %u seconds", sec);
|
||||||
|
setsockopt(state->sockfd, IPPROTO_TCP, TCP_KEEPINIT, &sec, sizeof(sec));
|
||||||
|
#elif defined(TCP_USER_TIMEOUT)
|
||||||
|
FF_DEBUG("Using TCP_USER_TIMEOUT: %u milliseconds", state->timeout);
|
||||||
|
setsockopt(state->sockfd, IPPROTO_TCP, TCP_USER_TIMEOUT, &state->timeout, sizeof(state->timeout));
|
||||||
|
#else
|
||||||
|
FF_DEBUG("Current platform does not support TCP connection timeout");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
error:
|
||||||
|
FF_DEBUG("Error occurred during initialization");
|
||||||
|
if (state->addr != NULL)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Releasing address information");
|
||||||
|
freeaddrinfo(state->addr);
|
||||||
|
state->addr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->sockfd > 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Closing socket: fd=%d", state->sockfd);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Preparing to send HTTP request: host=%s, path=%s", host, path);
|
||||||
|
|
||||||
|
if (state->compression)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Compression enabled, checking if zlib is available");
|
||||||
|
|
||||||
|
#ifdef FF_HAVE_ZLIB
|
||||||
|
const char* zlibError = ffNetworkingLoadZlibLibrary();
|
||||||
|
// Only enable compression if zlib library is successfully loaded
|
||||||
|
if (zlibError == NULL)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Successfully loaded zlib library, compression enabled");
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
|
||||||
|
state->compression = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
FF_DEBUG("zlib not supported at build time, compression disabled");
|
||||||
|
state->compression = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FF_DEBUG("Compression disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* initResult = initNetworkingState(state, host, path, headers);
|
||||||
|
if (initResult != NULL) {
|
||||||
|
FF_DEBUG("Initialization failed: %s", initResult);
|
||||||
|
return initResult;
|
||||||
|
}
|
||||||
|
FF_DEBUG("Network state initialization successful");
|
||||||
|
|
||||||
|
const char* tfoResult = tryNonThreadingFastPath(state);
|
||||||
|
if (tfoResult == NULL) {
|
||||||
|
FF_DEBUG("TryNonThreadingFastPath() succeeded or in progress");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
FF_DEBUG("TryNonThreadingFastPath() failed: %s, trying traditional connection", tfoResult);
|
||||||
|
|
||||||
|
#ifdef FF_HAVE_THREADS
|
||||||
|
if (instance.config.general.multithreading)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Multithreading mode enabled, creating connection thread");
|
||||||
|
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||||
|
if (state->thread) {
|
||||||
|
FF_DEBUG("Thread creation successful: thread=%p", (void*)state->thread);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
FF_DEBUG("Thread creation failed");
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Multithreading mode disabled, connecting in main thread");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return connectAndSend(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Preparing to receive HTTP response");
|
||||||
|
uint32_t timeout = state->timeout;
|
||||||
|
|
||||||
|
#ifdef FF_HAVE_THREADS
|
||||||
|
if (state->thread)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Connection thread is running, waiting for it to complete (timeout=%u ms)", timeout);
|
||||||
|
if (!ffThreadJoin(state->thread, timeout)) {
|
||||||
|
FF_DEBUG("Thread join failed or timed out");
|
||||||
|
return "ffThreadJoin() failed or timeout";
|
||||||
|
}
|
||||||
|
FF_DEBUG("Thread completed successfully");
|
||||||
|
state->thread = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(state->sockfd == -1)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Invalid socket, HTTP request might have failed");
|
||||||
|
return "ffNetworkingSendHttpRequest() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set larger initial receive buffer instead of small repeated receives
|
||||||
|
int rcvbuf = 65536; // 64KB
|
||||||
|
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// poll for the socket to be readable.
|
||||||
|
// Because of the non-blocking connectx() call, the connection might not be established yet
|
||||||
|
FF_DEBUG("Using poll() to check if socket is readable");
|
||||||
|
if (poll(&(struct pollfd) {
|
||||||
|
.fd = state->sockfd,
|
||||||
|
.events = POLLIN
|
||||||
|
}, 1, timeout > 0 ? (int) timeout : -1) == -1)
|
||||||
|
{
|
||||||
|
FF_DEBUG("poll() failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
return "poll() failed";
|
||||||
|
}
|
||||||
|
FF_DEBUG("Socket is readable, proceeding to receive data");
|
||||||
|
#else
|
||||||
|
if(timeout > 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Setting receive timeout: %u ms", timeout);
|
||||||
|
struct timeval timev;
|
||||||
|
timev.tv_sec = timeout / 1000;
|
||||||
|
timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); //milliseconds to microseconds
|
||||||
|
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FF_DEBUG("Starting data reception");
|
||||||
|
FF_MAYBE_UNUSED int recvCount = 0;
|
||||||
|
uint32_t contentLength = 0;
|
||||||
|
char* headerEnd = NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
|
||||||
|
++recvCount, buffer->length, ffStrbufGetFree(buffer));
|
||||||
|
|
||||||
|
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), MSG_WAITALL);
|
||||||
|
|
||||||
|
if (received <= 0) {
|
||||||
|
if (received == 0) {
|
||||||
|
FF_DEBUG("Connection closed (received=0)");
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Reception failed: %s (errno=%d)", strerror(errno), errno);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->length += (uint32_t) received;
|
||||||
|
buffer->chars[buffer->length] = '\0';
|
||||||
|
|
||||||
|
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
|
||||||
|
|
||||||
|
// Check if HTTP header end marker is found
|
||||||
|
if (headerEnd == NULL) {
|
||||||
|
headerEnd = memmem(buffer->chars, buffer->length, "\r\n\r\n", 4);
|
||||||
|
if (headerEnd != NULL) {
|
||||||
|
FF_DEBUG("Found HTTP header end marker, position: %ld", (long)(headerEnd - buffer->chars));
|
||||||
|
|
||||||
|
// Check for Content-Length header to pre-allocate enough memory
|
||||||
|
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
|
||||||
|
if (clHeader) {
|
||||||
|
contentLength = (uint32_t) strtoul(clHeader + 16, NULL, 10);
|
||||||
|
if (contentLength > 0) {
|
||||||
|
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
||||||
|
// Ensure buffer is large enough, adding header size and some margin
|
||||||
|
ffStrbufEnsureFree(buffer, contentLength + 16);
|
||||||
|
FF_DEBUG("Extended receive buffer to %u bytes", buffer->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (ffStrbufGetFree(buffer) > 0);
|
||||||
|
|
||||||
|
FF_DEBUG("Closing socket: fd=%d", state->sockfd);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
|
||||||
|
if (buffer->length == 0) {
|
||||||
|
FF_DEBUG("Server response is empty");
|
||||||
|
return "Empty server response received";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerEnd == NULL) {
|
||||||
|
FF_DEBUG("No HTTP header end marker found");
|
||||||
|
return "No HTTP header end found";
|
||||||
|
}
|
||||||
|
if (contentLength > 0 && buffer->length != contentLength + (uint32_t)(headerEnd - buffer->chars) + 4) {
|
||||||
|
FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + (uint32_t)(headerEnd - buffer->chars) + 4);
|
||||||
|
return "Content length mismatch";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
||||||
|
FF_DEBUG("Received valid HTTP 200 response, content %u bytes, total %u bytes", contentLength, buffer->length);
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||||
|
return "Invalid response";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If compression was used, try to decompress
|
||||||
|
#ifdef FF_HAVE_ZLIB
|
||||||
|
if (state->compression) {
|
||||||
|
FF_DEBUG("Content received, checking if compressed");
|
||||||
|
if (!ffNetworkingDecompressGzip(buffer, headerEnd)) {
|
||||||
|
FF_DEBUG("Decompression failed or invalid compression format");
|
||||||
|
return "Failed to decompress or invalid format";
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Decompression successful or no decompression needed, total length after decompression: %u bytes", buffer->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,339 @@
|
|||||||
|
#include <mswsock.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
//Must be included after <mswsock.h>
|
||||||
|
#include "fastfetch.h"
|
||||||
|
#include "common/networking/networking.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
#include "util/debug.h"
|
||||||
|
|
||||||
|
static LPFN_CONNECTEX ConnectEx;
|
||||||
|
|
||||||
|
static const char* initWsaData(WSADATA* wsaData)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Initializing WinSock");
|
||||||
|
if(WSAStartup(MAKEWORD(2, 2), wsaData) != 0) {
|
||||||
|
FF_DEBUG("WSAStartup() failed");
|
||||||
|
return "WSAStartup() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LOBYTE(wsaData->wVersion) != 2 || HIBYTE(wsaData->wVersion) != 2) {
|
||||||
|
FF_DEBUG("Invalid wsaData version found: %d.%d", LOBYTE(wsaData->wVersion), HIBYTE(wsaData->wVersion));
|
||||||
|
return "Invalid wsaData version found";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Dummy socket needed for WSAIoctl
|
||||||
|
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(sockfd == INVALID_SOCKET) {
|
||||||
|
FF_DEBUG("socket(AF_INET, SOCK_STREAM) failed");
|
||||||
|
return "socket(AF_INET, SOCK_STREAM) failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwBytes;
|
||||||
|
GUID guid = WSAID_CONNECTEX;
|
||||||
|
if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||||
|
&guid, sizeof(guid),
|
||||||
|
&ConnectEx, sizeof(ConnectEx),
|
||||||
|
&dwBytes, NULL, NULL) != 0) {
|
||||||
|
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
|
||||||
|
return "WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
closesocket(sockfd);
|
||||||
|
FF_DEBUG("WinSock initialized successfully");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Preparing to send HTTP request: host=%s, path=%s", host, path);
|
||||||
|
|
||||||
|
if (state->compression)
|
||||||
|
{
|
||||||
|
#ifdef FF_HAVE_ZLIB
|
||||||
|
const char* zlibError = ffNetworkingLoadZlibLibrary();
|
||||||
|
// Only enable compression if zlib library is successfully loaded
|
||||||
|
if (zlibError == NULL)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Successfully loaded zlib library, compression enabled");
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Failed to load zlib library, compression disabled: %s", zlibError);
|
||||||
|
state->compression = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
FF_DEBUG("zlib not supported at build time, compression disabled");
|
||||||
|
state->compression = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FF_DEBUG("Compression disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
static WSADATA wsaData;
|
||||||
|
if (wsaData.wVersion == 0)
|
||||||
|
{
|
||||||
|
const char* error = initWsaData(&wsaData);
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
wsaData.wVersion = (WORD) -1;
|
||||||
|
FF_DEBUG("WinSock initialization failed: %s", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wsaData.wVersion == (WORD) -1)
|
||||||
|
{
|
||||||
|
FF_DEBUG("WinSock initialization previously failed");
|
||||||
|
return "initWsaData() failed before";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo* addr;
|
||||||
|
struct addrinfo hints = {
|
||||||
|
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
||||||
|
.ai_socktype = SOCK_STREAM,
|
||||||
|
.ai_flags = AI_NUMERICSERV,
|
||||||
|
};
|
||||||
|
|
||||||
|
FF_DEBUG("Resolving address: %s (%s)", host, state->ipv6 ? "IPv6" : "IPv4");
|
||||||
|
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("getaddrinfo() failed");
|
||||||
|
return "getaddrinfo() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||||
|
if(state->sockfd == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
FF_DEBUG("socket() failed");
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
return "socket() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD flag = 1;
|
||||||
|
#ifdef TCP_NODELAY
|
||||||
|
// Enable TCP_NODELAY to disable Nagle's algorithm
|
||||||
|
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)) != 0) {
|
||||||
|
FF_DEBUG("Failed to set TCP_NODELAY: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Successfully disabled Nagle's algorithm");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set timeout if needed
|
||||||
|
if (state->timeout > 0) {
|
||||||
|
FF_DEBUG("Setting connection timeout: %u ms", state->timeout);
|
||||||
|
setsockopt(state->sockfd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&state->timeout, sizeof(state->timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
//ConnectEx requires the socket to be initially bound
|
||||||
|
if((state->ipv6
|
||||||
|
? bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in6) {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
.sin6_addr = in6addr_any,
|
||||||
|
}, sizeof(struct sockaddr_in6))
|
||||||
|
: bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = INADDR_ANY,
|
||||||
|
}, sizeof(struct sockaddr_in))) != 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("bind() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
return "bind() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize overlapped structure for asynchronous I/O
|
||||||
|
memset(&state->overlapped, 0, sizeof(OVERLAPPED));
|
||||||
|
|
||||||
|
// Build HTTP command
|
||||||
|
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64);
|
||||||
|
ffStrbufAppendS(&command, "GET ");
|
||||||
|
ffStrbufAppendS(&command, path);
|
||||||
|
ffStrbufAppendS(&command, " HTTP/1.0\nHost: ");
|
||||||
|
ffStrbufAppendS(&command, host);
|
||||||
|
ffStrbufAppendS(&command, "\r\n");
|
||||||
|
ffStrbufAppendS(&command, "Connection: close\r\n"); // Explicitly request connection closure
|
||||||
|
|
||||||
|
// Add compression support if enabled
|
||||||
|
if (state->compression) {
|
||||||
|
FF_DEBUG("Enabling HTTP content compression");
|
||||||
|
ffStrbufAppendS(&command, "Accept-Encoding: gzip\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendS(&command, headers);
|
||||||
|
ffStrbufAppendS(&command, "\r\n");
|
||||||
|
|
||||||
|
#ifdef TCP_FASTOPEN
|
||||||
|
if (state->tfo)
|
||||||
|
{
|
||||||
|
// Set TCP Fast Open
|
||||||
|
flag = 1;
|
||||||
|
if (setsockopt(state->sockfd, IPPROTO_TCP, TCP_FASTOPEN, (char*)&flag, sizeof(flag)) != 0) {
|
||||||
|
FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Successfully set TCP_FASTOPEN option");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FF_DEBUG("TCP Fast Open disabled");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FF_DEBUG("Using ConnectEx to send %u bytes of data", command.length);
|
||||||
|
DWORD sent = 0;
|
||||||
|
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen,
|
||||||
|
command.chars, command.length, &sent, &state->overlapped);
|
||||||
|
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
addr = NULL;
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
if (WSAGetLastError() != WSA_IO_PENDING)
|
||||||
|
{
|
||||||
|
FF_DEBUG("ConnectEx() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
return "ConnectEx() failed";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FF_DEBUG("ConnectEx() pending");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FF_DEBUG("ConnectEx() succeeded, sent %u bytes of data", (unsigned) sent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need to cleanup state fields here since we need them in the receive function
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Preparing to receive HTTP response");
|
||||||
|
|
||||||
|
if (state->sockfd == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Invalid socket, HTTP request might have failed");
|
||||||
|
return "ffNetworkingSendHttpRequest() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout = state->timeout;
|
||||||
|
if (timeout > 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("WaitForSingleObject with timeout: %u ms", timeout);
|
||||||
|
if (WaitForSingleObject((HANDLE)state->sockfd, timeout) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("WaitForSingleObject failed or timed out");
|
||||||
|
CancelIo((HANDLE) state->sockfd);
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
return "WaitForSingleObject(state->sockfd) failed or timeout";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD transfer, flags;
|
||||||
|
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
|
||||||
|
{
|
||||||
|
FF_DEBUG("WSAGetOverlappedResult failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
return "WSAGetOverlappedResult() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(timeout > 0)
|
||||||
|
{
|
||||||
|
FF_DEBUG("Setting receive timeout: %u ms", timeout);
|
||||||
|
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set larger receive buffer for better performance
|
||||||
|
int rcvbuf = 65536; // 64KB
|
||||||
|
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&rcvbuf, sizeof(rcvbuf));
|
||||||
|
|
||||||
|
FF_DEBUG("Starting data reception");
|
||||||
|
FF_MAYBE_UNUSED int recvCount = 0;
|
||||||
|
uint32_t contentLength = 0;
|
||||||
|
char* headerEnd = NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
|
||||||
|
++recvCount, buffer->length, ffStrbufGetFree(buffer));
|
||||||
|
|
||||||
|
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0);
|
||||||
|
|
||||||
|
if (received <= 0) {
|
||||||
|
if (received == 0) {
|
||||||
|
FF_DEBUG("Connection closed (received=0)");
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Reception failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->length += (uint32_t) received;
|
||||||
|
buffer->chars[buffer->length] = '\0';
|
||||||
|
|
||||||
|
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
|
||||||
|
|
||||||
|
// Check if HTTP header end marker is found
|
||||||
|
if (headerEnd == NULL) {
|
||||||
|
headerEnd = strstr(buffer->chars, "\r\n\r\n");
|
||||||
|
if (headerEnd != NULL) {
|
||||||
|
FF_DEBUG("Found HTTP header end marker, position: %ld", (long)(headerEnd - buffer->chars));
|
||||||
|
|
||||||
|
// Check for Content-Length header to pre-allocate enough memory
|
||||||
|
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
|
||||||
|
if (clHeader) {
|
||||||
|
contentLength = (uint32_t) strtoul(clHeader + 16, NULL, 10);
|
||||||
|
if (contentLength > 0) {
|
||||||
|
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
||||||
|
// Ensure buffer is large enough, adding header size and some margin
|
||||||
|
ffStrbufEnsureFree(buffer, contentLength + 16);
|
||||||
|
FF_DEBUG("Extended receive buffer to %u bytes", buffer->allocated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (ffStrbufGetFree(buffer) > 0);
|
||||||
|
|
||||||
|
FF_DEBUG("Closing socket: fd=%u", (unsigned)state->sockfd);
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
|
||||||
|
if (buffer->length == 0) {
|
||||||
|
FF_DEBUG("Server response is empty");
|
||||||
|
return "Empty server response received";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerEnd == NULL) {
|
||||||
|
FF_DEBUG("No HTTP header end marker found");
|
||||||
|
return "No HTTP header end found";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
||||||
|
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
|
||||||
|
contentLength, buffer->length);
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||||
|
return "Invalid response";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If compression was used, try to decompress
|
||||||
|
#ifdef FF_HAVE_ZLIB
|
||||||
|
if (state->compression) {
|
||||||
|
FF_DEBUG("Content received, checking if compressed");
|
||||||
|
if (!ffNetworkingDecompressGzip(buffer, headerEnd)) {
|
||||||
|
FF_DEBUG("Decompression failed or invalid compression format");
|
||||||
|
return "Failed to decompress or invalid format";
|
||||||
|
} else {
|
||||||
|
FF_DEBUG("Decompression successful or no decompression needed, total length after decompression: %u bytes", buffer->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
#include "fastfetch.h"
|
|
||||||
#include "common/networking.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <netinet/in.h> // For FreeBSD
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
|
|
||||||
static const char* connectAndSend(FFNetworkingState* state)
|
|
||||||
{
|
|
||||||
const char* ret = NULL;
|
|
||||||
struct addrinfo* addr;
|
|
||||||
|
|
||||||
if(getaddrinfo(state->host.chars, "80", &(struct addrinfo) {
|
|
||||||
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
|
||||||
.ai_socktype = SOCK_STREAM,
|
|
||||||
}, &addr) != 0)
|
|
||||||
{
|
|
||||||
ret = "getaddrinfo() failed";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
|
||||||
if(state->sockfd == -1)
|
|
||||||
{
|
|
||||||
freeaddrinfo(addr);
|
|
||||||
ret = "socket() failed";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->timeout > 0)
|
|
||||||
{
|
|
||||||
FF_MAYBE_UNUSED uint32_t sec = state->timeout / 1000;
|
|
||||||
if (sec == 0) sec = 1;
|
|
||||||
|
|
||||||
#ifdef TCP_CONNECTIONTIMEOUT
|
|
||||||
setsockopt(state->sockfd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &sec, sizeof(sec));
|
|
||||||
#elif defined(TCP_KEEPINIT)
|
|
||||||
setsockopt(state->sockfd, IPPROTO_TCP, TCP_KEEPINIT, &sec, sizeof(sec));
|
|
||||||
#elif defined(TCP_USER_TIMEOUT)
|
|
||||||
setsockopt(state->sockfd, IPPROTO_TCP, TCP_USER_TIMEOUT, &state->timeout, sizeof(state->timeout));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
|
||||||
{
|
|
||||||
close(state->sockfd);
|
|
||||||
freeaddrinfo(addr);
|
|
||||||
ret = "connect() failed";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
freeaddrinfo(addr);
|
|
||||||
|
|
||||||
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
|
||||||
{
|
|
||||||
close(state->sockfd);
|
|
||||||
ret = "send() failed";
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
error:
|
|
||||||
state->sockfd = -1;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
ffStrbufDestroy(&state->host);
|
|
||||||
ffStrbufDestroy(&state->command);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
|
||||||
|
|
||||||
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
|
||||||
{
|
|
||||||
ffStrbufInitS(&state->host, host);
|
|
||||||
|
|
||||||
ffStrbufInitA(&state->command, 64);
|
|
||||||
ffStrbufAppendS(&state->command, "GET ");
|
|
||||||
ffStrbufAppendS(&state->command, path);
|
|
||||||
ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: ");
|
|
||||||
ffStrbufAppendS(&state->command, host);
|
|
||||||
ffStrbufAppendS(&state->command, "\r\n");
|
|
||||||
ffStrbufAppendS(&state->command, headers);
|
|
||||||
ffStrbufAppendS(&state->command, "\r\n");
|
|
||||||
|
|
||||||
#ifdef FF_HAVE_THREADS
|
|
||||||
if (instance.config.general.multithreading)
|
|
||||||
{
|
|
||||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
|
||||||
return state->thread ? NULL : "ffThreadCreate(connectAndSend) failed";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return connectAndSend(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
|
||||||
{
|
|
||||||
uint32_t timeout = state->timeout;
|
|
||||||
|
|
||||||
#ifdef FF_HAVE_THREADS
|
|
||||||
if (instance.config.general.multithreading)
|
|
||||||
{
|
|
||||||
if (!ffThreadJoin(state->thread, timeout))
|
|
||||||
return "ffThreadJoin() failed or timeout";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(state->sockfd == -1)
|
|
||||||
return "ffNetworkingSendHttpRequest() failed";
|
|
||||||
|
|
||||||
if(timeout > 0)
|
|
||||||
{
|
|
||||||
struct timeval timev;
|
|
||||||
timev.tv_sec = timeout / 1000;
|
|
||||||
timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); //milliseconds to microseconds
|
|
||||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t recvStart;
|
|
||||||
do {
|
|
||||||
recvStart = buffer->length;
|
|
||||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
|
||||||
if (received <= 0) break;
|
|
||||||
buffer->length += (uint32_t) received;
|
|
||||||
buffer->chars[buffer->length] = '\0';
|
|
||||||
} while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL);
|
|
||||||
|
|
||||||
close(state->sockfd);
|
|
||||||
if (buffer->length == 0) return "Empty server response received";
|
|
||||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
#include <mswsock.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
|
|
||||||
//Must be included after <mswsock.h>
|
|
||||||
#include "fastfetch.h"
|
|
||||||
#include "common/networking.h"
|
|
||||||
|
|
||||||
static LPFN_CONNECTEX ConnectEx;
|
|
||||||
|
|
||||||
static const char* initWsaData(WSADATA* wsaData)
|
|
||||||
{
|
|
||||||
if(WSAStartup(MAKEWORD(2, 2), wsaData) != 0)
|
|
||||||
return "WSAStartup() failed";
|
|
||||||
|
|
||||||
if(LOBYTE(wsaData->wVersion) != 2 || HIBYTE(wsaData->wVersion) != 2)
|
|
||||||
return "Invalid wsaData version found";
|
|
||||||
|
|
||||||
//Dummy socket needed for WSAIoctl
|
|
||||||
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if(sockfd == INVALID_SOCKET)
|
|
||||||
return "socket(AF_INET, SOCK_STREAM) failed";
|
|
||||||
|
|
||||||
DWORD dwBytes;
|
|
||||||
GUID guid = WSAID_CONNECTEX;
|
|
||||||
if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
|
||||||
&guid, sizeof(guid),
|
|
||||||
&ConnectEx, sizeof(ConnectEx),
|
|
||||||
&dwBytes, NULL, NULL) != 0)
|
|
||||||
return "WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed";
|
|
||||||
|
|
||||||
closesocket(sockfd);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
|
||||||
{
|
|
||||||
static WSADATA wsaData;
|
|
||||||
if (wsaData.wVersion == 0)
|
|
||||||
{
|
|
||||||
const char* error = initWsaData(&wsaData);
|
|
||||||
if (error != NULL)
|
|
||||||
{
|
|
||||||
wsaData.wVersion = (WORD) -1;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (wsaData.wVersion == (WORD) -1)
|
|
||||||
return "initWsaData() failed before";
|
|
||||||
|
|
||||||
struct addrinfo* addr;
|
|
||||||
|
|
||||||
if(getaddrinfo(host, "80", &(struct addrinfo) {
|
|
||||||
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
|
|
||||||
.ai_socktype = SOCK_STREAM,
|
|
||||||
}, &addr) != 0)
|
|
||||||
return "getaddrinfo() failed";
|
|
||||||
|
|
||||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
|
||||||
if(state->sockfd == INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
freeaddrinfo(addr);
|
|
||||||
return "socket() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//ConnectEx requires the socket to be initially bound
|
|
||||||
if((state->ipv6
|
|
||||||
? bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in6) {
|
|
||||||
.sin6_family = AF_INET6,
|
|
||||||
.sin6_addr = in6addr_any,
|
|
||||||
}, sizeof(struct sockaddr_in6))
|
|
||||||
: bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) {
|
|
||||||
.sin_family = AF_INET,
|
|
||||||
.sin_addr.s_addr = INADDR_ANY,
|
|
||||||
}, sizeof(struct sockaddr_in))) != 0)
|
|
||||||
{
|
|
||||||
closesocket(state->sockfd);
|
|
||||||
freeaddrinfo(addr);
|
|
||||||
state->sockfd = INVALID_SOCKET;
|
|
||||||
return "bind() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64);
|
|
||||||
ffStrbufAppendS(&command, "GET ");
|
|
||||||
ffStrbufAppendS(&command, path);
|
|
||||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
|
||||||
ffStrbufAppendS(&command, host);
|
|
||||||
ffStrbufAppendS(&command, "\r\n");
|
|
||||||
ffStrbufAppendS(&command, headers);
|
|
||||||
ffStrbufAppendS(&command, "\r\n");
|
|
||||||
|
|
||||||
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen, command.chars, command.length, NULL, &state->overlapped);
|
|
||||||
freeaddrinfo(addr);
|
|
||||||
|
|
||||||
if(!result && WSAGetLastError() != WSA_IO_PENDING)
|
|
||||||
{
|
|
||||||
closesocket(state->sockfd);
|
|
||||||
state->sockfd = INVALID_SOCKET;
|
|
||||||
return "ConnectEx() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
|
|
||||||
{
|
|
||||||
if (state->sockfd == INVALID_SOCKET)
|
|
||||||
return "ffNetworkingSendHttpRequest() failed";
|
|
||||||
|
|
||||||
uint32_t timeout = state->timeout;
|
|
||||||
if (timeout > 0)
|
|
||||||
{
|
|
||||||
if (WaitForSingleObject((HANDLE) state->sockfd, timeout) != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
CancelIo((HANDLE) state->sockfd);
|
|
||||||
closesocket(state->sockfd);
|
|
||||||
return "WaitForSingleObject(state->sockfd) failed or timeout";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD transfer, flags;
|
|
||||||
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
|
|
||||||
{
|
|
||||||
closesocket(state->sockfd);
|
|
||||||
return "WSAGetOverlappedResult() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(timeout > 0)
|
|
||||||
{
|
|
||||||
//https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
|
|
||||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &timeout, sizeof(timeout));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t recvStart;
|
|
||||||
do {
|
|
||||||
recvStart = buffer->length;
|
|
||||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int) ffStrbufGetFree(buffer), 0);
|
|
||||||
if (received <= 0) break;
|
|
||||||
buffer->length = recvStart + (uint32_t) received;
|
|
||||||
buffer->chars[buffer->length] = '\0';
|
|
||||||
} while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL);
|
|
||||||
|
|
||||||
closesocket(state->sockfd);
|
|
||||||
if (buffer->length == 0) return "Empty server response received";
|
|
||||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
|
|
||||||
}
|
|
||||||
@@ -198,6 +198,12 @@ void ffParseDuration(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t s
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(seconds >= 30)
|
||||||
|
{
|
||||||
|
minutes++;
|
||||||
|
seconds = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(days > 0)
|
if(days > 0)
|
||||||
{
|
{
|
||||||
ffStrbufAppendF(result, "%u day", days);
|
ffStrbufAppendF(result, "%u day", days);
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
#include <OS.h>
|
||||||
|
#include <image.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||||
@@ -310,6 +313,21 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
|||||||
}
|
}
|
||||||
kvm_close(kd);
|
kvm_close(kd);
|
||||||
|
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
|
||||||
|
image_info info;
|
||||||
|
int32 cookie = 0;
|
||||||
|
|
||||||
|
while (get_next_image_info(pid, &cookie, &info) == B_OK)
|
||||||
|
{
|
||||||
|
if (info.type != B_APP_IMAGE) continue;
|
||||||
|
ffStrbufSetS(exe, info.name);
|
||||||
|
|
||||||
|
if (exePath)
|
||||||
|
ffStrbufSet(exePath, exe);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(exe->length == 0)
|
if(exe->length == 0)
|
||||||
@@ -476,6 +494,18 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
|||||||
if (!proc)
|
if (!proc)
|
||||||
return "kvm_getprocs() failed";
|
return "kvm_getprocs() failed";
|
||||||
|
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
|
||||||
|
team_info info;
|
||||||
|
if (get_team_info(pid, &info) == B_OK)
|
||||||
|
{
|
||||||
|
ffStrbufSetS(name, info.name);
|
||||||
|
if (ppid)
|
||||||
|
*ppid = info.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_UNUSED(tty);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return "Unsupported platform";
|
return "Unsupported platform";
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig confi
|
|||||||
|
|
||||||
switch (options->tempUnit)
|
switch (options->tempUnit)
|
||||||
{
|
{
|
||||||
|
case FF_TEMPERATURE_UNIT_DEFAULT:
|
||||||
case FF_TEMPERATURE_UNIT_CELSIUS:
|
case FF_TEMPERATURE_UNIT_CELSIUS:
|
||||||
ffStrbufAppendF(buffer, "%.*f°C", options->tempNdigits, celsius);
|
ffStrbufAppendF(buffer, "%.*f°C", options->tempNdigits, celsius);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+2
-2
@@ -65,8 +65,8 @@
|
|||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
|
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
|
||||||
{
|
{
|
||||||
ts.tv_sec += ts.tv_sec / 1000;
|
ts.tv_sec += timeout / 1000;
|
||||||
ts.tv_nsec += (ts.tv_nsec % 1000) * 1000000;
|
ts.tv_nsec += (timeout % 1000) * 1000000;
|
||||||
if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
|
if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
|
||||||
{
|
{
|
||||||
pthread_kill(thread, SIGTERM);
|
pthread_kill(thread, SIGTERM);
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <synchapi.h>
|
#include <synchapi.h>
|
||||||
#include <profileapi.h>
|
#include <profileapi.h>
|
||||||
#include <sysinfoapi.h>
|
#include <sysinfoapi.h>
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
#include <OS.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline double ffTimeGetTick(void) //In msec
|
static inline double ffTimeGetTick(void) //In msec
|
||||||
@@ -17,6 +19,8 @@ static inline double ffTimeGetTick(void) //In msec
|
|||||||
LARGE_INTEGER start;
|
LARGE_INTEGER start;
|
||||||
QueryPerformanceCounter(&start);
|
QueryPerformanceCounter(&start);
|
||||||
return (double) start.QuadPart * 1000 / (double) frequency.QuadPart;
|
return (double) start.QuadPart * 1000 / (double) frequency.QuadPart;
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
return (double) system_time() / 1000.;
|
||||||
#else
|
#else
|
||||||
struct timespec timeNow;
|
struct timespec timeNow;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||||
@@ -30,6 +34,8 @@ static inline uint64_t ffTimeGetNow(void)
|
|||||||
uint64_t timeNow;
|
uint64_t timeNow;
|
||||||
GetSystemTimeAsFileTime((FILETIME*) &timeNow);
|
GetSystemTimeAsFileTime((FILETIME*) &timeNow);
|
||||||
return (timeNow - 116444736000000000ull) / 10000ull;
|
return (timeNow - 116444736000000000ull) / 10000ull;
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
return (uint64_t) real_time_clock_usecs() / 1000u;
|
||||||
#else
|
#else
|
||||||
struct timespec timeNow;
|
struct timespec timeNow;
|
||||||
clock_gettime(CLOCK_REALTIME, &timeNow);
|
clock_gettime(CLOCK_REALTIME, &timeNow);
|
||||||
@@ -76,6 +82,18 @@ static inline const char* ffTimeToShortStr(uint64_t msec)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not thread-safe
|
||||||
|
static inline const char* ffTimeToTimeStr(uint64_t msec)
|
||||||
|
{
|
||||||
|
if (msec == 0) return "";
|
||||||
|
time_t tsec = (time_t) (msec / 1000);
|
||||||
|
|
||||||
|
static char buf[32];
|
||||||
|
strftime(buf, sizeof(buf), "%T", localtime(&tsec));
|
||||||
|
sprintf(buf + __builtin_strlen("00:00:00"), ".%03u", (unsigned) (msec % 1000));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+6
-16
@@ -104,16 +104,6 @@
|
|||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"long": "escape-bedrock",
|
|
||||||
"desc": "On Bedrock Linux, whether to escape the bedrock jail",
|
|
||||||
"remark": "Linux only",
|
|
||||||
"arg": {
|
|
||||||
"type": "bool",
|
|
||||||
"optional": true,
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"long": "wmi-timeout",
|
"long": "wmi-timeout",
|
||||||
"desc": "Set the timeout (ms) for WMI queries",
|
"desc": "Set the timeout (ms) for WMI queries",
|
||||||
@@ -693,8 +683,8 @@
|
|||||||
"type": "enum",
|
"type": "enum",
|
||||||
"enum": {
|
"enum": {
|
||||||
"IEC": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ...",
|
"IEC": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ...",
|
||||||
"SI": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ...",
|
"SI": "1000 Bytes = 1 kB, 1000 kB = 1 MB, ...",
|
||||||
"JEDEC": "1024 Bytes = 1 kB, 1024 kB = 1 MB, ..."
|
"JEDEC": "1024 Bytes = 1 KB, 1024 KB = 1 MB, ..."
|
||||||
},
|
},
|
||||||
"default": "IEC"
|
"default": "IEC"
|
||||||
}
|
}
|
||||||
@@ -732,11 +722,12 @@
|
|||||||
"arg": {
|
"arg": {
|
||||||
"type": "enum",
|
"type": "enum",
|
||||||
"enum": {
|
"enum": {
|
||||||
|
"D": "Default",
|
||||||
"C": "Celsius",
|
"C": "Celsius",
|
||||||
"F": "Fahrenheit",
|
"F": "Fahrenheit",
|
||||||
"K": "Kelvin"
|
"K": "Kelvin"
|
||||||
},
|
},
|
||||||
"default": "C"
|
"default": "D"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1428,10 +1419,9 @@
|
|||||||
"arg": {
|
"arg": {
|
||||||
"type": "enum",
|
"type": "enum",
|
||||||
"enum": {
|
"enum": {
|
||||||
"auto": "Auto detection",
|
"auto": "Prefer EGL on *nix; prefer platform specific implementation on others",
|
||||||
"egl": "EGL",
|
"egl": "EGL",
|
||||||
"glx": "GLX",
|
"glx": "GLX (*nix only)"
|
||||||
"osmesa": "OSMesa"
|
|
||||||
},
|
},
|
||||||
"default": "auto"
|
"default": "auto"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
|||||||
// https://github.com/AsahiLinux/linux/blob/b5c05cbffb0488c7618106926d522cc3b43d93d5/drivers/power/supply/macsmc_power.c#L410-L419
|
// https://github.com/AsahiLinux/linux/blob/b5c05cbffb0488c7618106926d522cc3b43d93d5/drivers/power/supply/macsmc_power.c#L410-L419
|
||||||
int year = (manufactureDate[0] - '0') * 10 + (manufactureDate[1] - '0') + 2000 - 8;
|
int year = (manufactureDate[0] - '0') * 10 + (manufactureDate[1] - '0') + 2000 - 8;
|
||||||
int month = (manufactureDate[2] - '0') * 10 + (manufactureDate[3] - '0');
|
int month = (manufactureDate[2] - '0') * 10 + (manufactureDate[3] - '0');
|
||||||
int day = (manufactureDate[4] - '0') * 10 + (manufactureDate[3] - '5');
|
int day = (manufactureDate[4] - '0') * 10 + (manufactureDate[3] - '0');
|
||||||
ffStrbufSetF(&battery->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
|
ffStrbufSetF(&battery->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include "fastfetch.h"
|
||||||
|
#include "battery.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
|
|
||||||
|
#include <private/device/power_managment.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
const char* parseBattery(int dfd, const char* battId, FFlist* results)
|
||||||
|
{
|
||||||
|
FF_AUTO_CLOSE_FD int fd = openat(dfd, battId, O_RDWR);
|
||||||
|
if (fd < 0) return "openat() failed";
|
||||||
|
|
||||||
|
acpi_battery_info basic = {};
|
||||||
|
if (ioctl(fd, GET_BATTERY_INFO, &basic, sizeof(basic)) != 0)
|
||||||
|
return "ioctl(GET_BATTERY_INFO) failed";
|
||||||
|
acpi_extended_battery_info extended = {};
|
||||||
|
if (ioctl(fd, GET_EXTENDED_BATTERY_INFO, &extended, sizeof(extended)) != 0)
|
||||||
|
return "ioctl(GET_EXTENDED_BATTERY_INFO) failed";
|
||||||
|
|
||||||
|
if (extended.last_full_charge == (uint32)-1)
|
||||||
|
return "Skipped";
|
||||||
|
|
||||||
|
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
|
||||||
|
ffStrbufInitS(&battery->modelName, extended.model_number);
|
||||||
|
ffStrbufInitS(&battery->manufacturer, extended.oem_info);
|
||||||
|
ffStrbufInit(&battery->manufactureDate);
|
||||||
|
ffStrbufInitS(&battery->technology, extended.type); // extended.technology?
|
||||||
|
ffStrbufInit(&battery->status);
|
||||||
|
ffStrbufInitS(&battery->serial, extended.serial_number);
|
||||||
|
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||||
|
battery->cycleCount = extended.cycles;
|
||||||
|
battery->timeRemaining = -1;
|
||||||
|
battery->capacity = (double) basic.capacity * 100. / (double) extended.last_full_charge;
|
||||||
|
|
||||||
|
if (basic.state & BATTERY_DISCHARGING)
|
||||||
|
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||||
|
if (basic.state & BATTERY_CHARGING)
|
||||||
|
ffStrbufAppendS(&battery->status, "Charging, ");
|
||||||
|
if (basic.state & BATTERY_CRITICAL_STATE)
|
||||||
|
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||||
|
if (basic.state & BATTERY_NOT_CHARGING)
|
||||||
|
ffStrbufAppendS(&battery->status, "AC Connected, ");
|
||||||
|
ffStrbufTrimRight(&battery->status, ' ');
|
||||||
|
ffStrbufTrimRight(&battery->status, ',');
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
|
||||||
|
{
|
||||||
|
FF_AUTO_CLOSE_DIR DIR* dir = opendir("/dev/power/acpi_battery/");
|
||||||
|
if (!dir) return "opendir(/dev/power/acpi_battery) failed";
|
||||||
|
|
||||||
|
struct dirent* entry;
|
||||||
|
while ((entry = readdir(dir)))
|
||||||
|
{
|
||||||
|
if (entry->d_name[0] == '.') continue;
|
||||||
|
parseBattery(dirfd(dir), entry->d_name, results);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -108,7 +108,7 @@ static void parseBattery(int dfd, const char* id, FFBatteryOptions* options, FFl
|
|||||||
|
|
||||||
if (ffReadFileBufferRelative(dfd, "capacity_level", &tmpBuffer))
|
if (ffReadFileBufferRelative(dfd, "capacity_level", &tmpBuffer))
|
||||||
{
|
{
|
||||||
ffStrbufTrimRightSpace(&result->manufacturer);
|
ffStrbufTrimRightSpace(&tmpBuffer);
|
||||||
if (ffStrbufEqualS(&tmpBuffer, "Critical"))
|
if (ffStrbufEqualS(&tmpBuffer, "Critical"))
|
||||||
{
|
{
|
||||||
if (result->status.length)
|
if (result->status.length)
|
||||||
|
|||||||
@@ -70,9 +70,7 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
|||||||
critical = true;
|
critical = true;
|
||||||
}
|
}
|
||||||
else if (ffStrEquals(desc, "discharge rate"))
|
else if (ffStrEquals(desc, "discharge rate"))
|
||||||
{
|
|
||||||
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
|
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max > 0)
|
if (max > 0)
|
||||||
@@ -92,7 +90,10 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
|||||||
if (charging)
|
if (charging)
|
||||||
ffStrbufAppendS(&battery->status, "Charging, ");
|
ffStrbufAppendS(&battery->status, "Charging, ");
|
||||||
else if (dischargeRate)
|
else if (dischargeRate)
|
||||||
|
{
|
||||||
ffStrbufAppendS(&battery->status, "Discharging, ");
|
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||||
|
battery->timeRemaining = (int32_t)((double)curr / dischargeRate * 3600);
|
||||||
|
}
|
||||||
if (critical)
|
if (critical)
|
||||||
ffStrbufAppendS(&battery->status, "Critical, ");
|
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||||
if (acConnected)
|
if (acConnected)
|
||||||
@@ -100,8 +101,11 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
|||||||
ffStrbufTrimRight(&battery->status, ' ');
|
ffStrbufTrimRight(&battery->status, ' ');
|
||||||
ffStrbufTrimRight(&battery->status, ',');
|
ffStrbufTrimRight(&battery->status, ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prop_object_iterator_release(iter);
|
||||||
}
|
}
|
||||||
prop_object_iterator_release(itKey);
|
prop_object_iterator_release(itKey);
|
||||||
|
prop_object_release(root);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const char* ffDetectBios(FFBiosResult* result)
|
|||||||
{
|
{
|
||||||
ffStrbufSetStatic(&result->type,
|
ffStrbufSetStatic(&result->type,
|
||||||
ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) ||
|
ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) ||
|
||||||
ffPathExists("/boot/efi/efi/" /*efi partition*/, FF_PATHTYPE_DIRECTORY)
|
ffPathExists("/boot/efi/efi/" /*efi partition. Note /boot/efi exists on BIOS system*/, FF_PATHTYPE_DIRECTORY)
|
||||||
? "UEFI" : "BIOS");
|
? "UEFI" : "BIOS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
const char *ffDetectBios(FFBiosResult *bios)
|
const char* ffDetectBios(FFBiosResult* bios)
|
||||||
{
|
{
|
||||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date);
|
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date);
|
||||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
|
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
||||||
|
#elif __OpenBSD__
|
||||||
|
#include "common/io/io.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct FFSmbiosBios
|
typedef struct FFSmbiosBios
|
||||||
@@ -89,6 +94,9 @@ const char* ffDetectBios(FFBiosResult* bios)
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif __HAIKU__ || __OpenBSD__
|
||||||
|
// Currently SMBIOS detection is supported in legancy BIOS only
|
||||||
|
ffStrbufSetStatic(&bios->type, "BIOS");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MA
|
|||||||
if (bt_devenum((void*) enumDev, devices) < 0)
|
if (bt_devenum((void*) enumDev, devices) < 0)
|
||||||
return "bt_devenum() failed";
|
return "bt_devenum() failed";
|
||||||
|
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
extern "C" {
|
||||||
|
#include "bluetooth.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <bluetooth/LocalDevice.h>
|
||||||
|
|
||||||
|
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
|
||||||
|
{
|
||||||
|
using namespace Bluetooth;
|
||||||
|
FF_SUPPRESS_IO();
|
||||||
|
|
||||||
|
LocalDevice* dev = LocalDevice::GetLocalDevice();
|
||||||
|
if (!dev) return NULL;
|
||||||
|
|
||||||
|
BString devClass;
|
||||||
|
dev->GetDeviceClass().DumpDeviceClass(devClass);
|
||||||
|
|
||||||
|
FFBluetoothResult* device = (FFBluetoothResult*) ffListAdd(devices);
|
||||||
|
ffStrbufInitS(&device->name, dev->GetFriendlyName());
|
||||||
|
ffStrbufInitS(&device->address, bdaddrUtils::ToString(dev->GetBluetoothAddress()).String());
|
||||||
|
ffStrbufInitS(&device->type, devClass.String());
|
||||||
|
device->battery = 0;
|
||||||
|
device->connected = true;
|
||||||
|
|
||||||
|
// TODO: more devices?
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
#import <IOBluetooth/IOBluetooth.h>
|
#import <IOBluetooth/IOBluetooth.h>
|
||||||
|
|
||||||
// For some reason the official declaration of IOBluetoothHostController don't include property `controllers`
|
// For some reason the official declaration of IOBluetoothHostController doesn't include property `controllers`
|
||||||
@interface IOBluetoothHostController()
|
@interface IOBluetoothHostController()
|
||||||
+ (id)controllers;
|
+ (id)controllers;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothResult */)
|
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
||||||
{
|
{
|
||||||
NSArray<IOBluetoothHostController*>* ctrls = IOBluetoothHostController.controllers;
|
NSArray<IOBluetoothHostController*>* ctrls = IOBluetoothHostController.controllers;
|
||||||
if(!ctrls)
|
if(!ctrls)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
|||||||
ffStrbufInitS(&device->name, blri.localInfo.name);
|
ffStrbufInitS(&device->name, blri.localInfo.name);
|
||||||
|
|
||||||
BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address };
|
BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address };
|
||||||
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
|
ffStrbufInitF(&device->address, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
addr.rgBytes[5],
|
addr.rgBytes[5],
|
||||||
addr.rgBytes[4],
|
addr.rgBytes[4],
|
||||||
addr.rgBytes[3],
|
addr.rgBytes[3],
|
||||||
@@ -97,6 +97,8 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
|||||||
device->enabled = true;
|
device->enabled = true;
|
||||||
device->connectable = ffBluetoothIsConnectable(hRadio);
|
device->connectable = ffBluetoothIsConnectable(hRadio);
|
||||||
device->discoverable = ffBluetoothIsDiscoverable(hRadio);
|
device->discoverable = ffBluetoothIsDiscoverable(hRadio);
|
||||||
|
|
||||||
|
CloseHandle(hRadio);
|
||||||
} while (ffBluetoothFindNextRadio(hFind, &hRadio));
|
} while (ffBluetoothFindNextRadio(hFind, &hRadio));
|
||||||
|
|
||||||
ffBluetoothFindRadioClose(hFind);
|
ffBluetoothFindRadioClose(hFind);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ typedef struct FFBootmgrResult
|
|||||||
{
|
{
|
||||||
FFstrbuf name;
|
FFstrbuf name;
|
||||||
FFstrbuf firmware;
|
FFstrbuf firmware;
|
||||||
|
uint16_t order;
|
||||||
bool secureBoot;
|
bool secureBoot;
|
||||||
} FFBootmgrResult;
|
} FFBootmgrResult;
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,22 @@
|
|||||||
#include "efi_helper.h"
|
#include "efi_helper.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
|
|
||||||
#include <sys/efiio.h>
|
#ifdef __OpenBSD__
|
||||||
|
#include <dev/efi/efiio.h>
|
||||||
|
#else
|
||||||
|
#include <sys/efiio.h>
|
||||||
|
#endif
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
typedef uint16_t efi_char;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EFI_GLOBAL_VARIABLE
|
||||||
|
#define EFI_GLOBAL_VARIABLE { 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, { 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c } }
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* ffDetectBootmgr(FFBootmgrResult* result)
|
const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||||
{
|
{
|
||||||
FF_AUTO_CLOSE_FD int efifd = open("/dev/efi", O_RDWR);
|
FF_AUTO_CLOSE_FD int efifd = open("/dev/efi", O_RDWR);
|
||||||
@@ -13,7 +25,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
|||||||
|
|
||||||
uint8_t buffer[2048];
|
uint8_t buffer[2048];
|
||||||
struct efi_var_ioc ioc = {
|
struct efi_var_ioc ioc = {
|
||||||
.vendor = { 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, { 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c } },
|
.vendor = EFI_GLOBAL_VARIABLE,
|
||||||
.data = buffer,
|
.data = buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,8 +35,10 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
|||||||
if (ioctl(efifd, EFIIOC_VAR_GET, &ioc) < 0 || ioc.datasize != 2)
|
if (ioctl(efifd, EFIIOC_VAR_GET, &ioc) < 0 || ioc.datasize != 2)
|
||||||
return "ioctl(EFIIOC_VAR_GET, BootCurrent) failed";
|
return "ioctl(EFIIOC_VAR_GET, BootCurrent) failed";
|
||||||
|
|
||||||
|
result->order = *(uint16_t*)buffer;
|
||||||
|
|
||||||
unsigned char hex[5];
|
unsigned char hex[5];
|
||||||
snprintf((char*) hex, sizeof(hex), "%04X", *(uint16_t*)buffer);
|
snprintf((char*) hex, sizeof(hex), "%04X", result->order);
|
||||||
ioc.datasize = sizeof(buffer);
|
ioc.datasize = sizeof(buffer);
|
||||||
ioc.name = (efi_char[]){ 'B', 'o', 'o', 't', hex[0], hex[1], hex[2], hex[3], '\0' };
|
ioc.name = (efi_char[]){ 'B', 'o', 'o', 't', hex[0], hex[1], hex[2], hex[3], '\0' };
|
||||||
ioc.namesize = sizeof("Boot####") * 2;
|
ioc.namesize = sizeof("Boot####") * 2;
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
|||||||
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "BootCurrent-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) != 6)
|
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "BootCurrent-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) != 6)
|
||||||
return "Failed to read efivar: BootCurrent";
|
return "Failed to read efivar: BootCurrent";
|
||||||
|
|
||||||
uint16_t value = *(uint16_t *)&buffer[4];
|
|
||||||
snprintf((char*) buffer, sizeof(buffer), FF_EFIVARS_PATH_PREFIX "Boot%04X-" FF_EFI_GLOBAL_GUID, value);
|
result->order = *(uint16_t *)&buffer[4];
|
||||||
|
|
||||||
|
snprintf((char*) buffer, sizeof(buffer), FF_EFIVARS_PATH_PREFIX "Boot%04X-" FF_EFI_GLOBAL_GUID, result->order);
|
||||||
|
|
||||||
ssize_t size = ffReadFileData((const char*) buffer, sizeof(buffer), buffer);
|
ssize_t size = ffReadFileData((const char*) buffer, sizeof(buffer), buffer);
|
||||||
if (size < 5 + (int) sizeof(FFEfiLoadOption) || size == (ssize_t) sizeof(buffer))
|
if (size < 5 + (int) sizeof(FFEfiLoadOption) || size == (ssize_t) sizeof(buffer))
|
||||||
@@ -20,7 +22,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
|||||||
|
|
||||||
ffEfiFillLoadOption((FFEfiLoadOption *)&buffer[4], result);
|
ffEfiFillLoadOption((FFEfiLoadOption *)&buffer[4], result);
|
||||||
|
|
||||||
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "SecureBoot-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) == 6)
|
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "SecureBoot-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) >= 5)
|
||||||
result->secureBoot = buffer[4] == 1;
|
result->secureBoot = buffer[4] == 1;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#include "bootmgr.h"
|
#include "bootmgr.h"
|
||||||
#include "efi_helper.h"
|
#include "efi_helper.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
const char* enablePrivilege(const wchar_t* privilege)
|
const char* enablePrivilege(const wchar_t* privilege)
|
||||||
{
|
{
|
||||||
HANDLE token;
|
FF_AUTO_CLOSE_FD HANDLE token = NULL;
|
||||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
||||||
return "OpenProcessToken() failed";
|
return "OpenProcessToken() failed";
|
||||||
|
|
||||||
@@ -32,13 +33,12 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
|||||||
if (enablePrivilege(L"SeSystemEnvironmentPrivilege") != NULL)
|
if (enablePrivilege(L"SeSystemEnvironmentPrivilege") != NULL)
|
||||||
return "Failed to enable SeSystemEnvironmentPrivilege";
|
return "Failed to enable SeSystemEnvironmentPrivilege";
|
||||||
|
|
||||||
uint16_t value;
|
if (GetFirmwareEnvironmentVariableW(L"BootCurrent", L"{" FF_EFI_GLOBAL_GUID L"}", &result->order, sizeof(result->order)) != 2)
|
||||||
if (GetFirmwareEnvironmentVariableW(L"BootCurrent", L"{" FF_EFI_GLOBAL_GUID L"}", &value, sizeof(value)) != 2)
|
|
||||||
return "GetFirmwareEnvironmentVariableW(BootCurrent) failed";
|
return "GetFirmwareEnvironmentVariableW(BootCurrent) failed";
|
||||||
|
|
||||||
uint8_t buffer[2048];
|
uint8_t buffer[2048];
|
||||||
wchar_t key[16];
|
wchar_t key[16];
|
||||||
swprintf(key, ARRAY_SIZE(key), L"Boot%04X", value);
|
swprintf(key, ARRAY_SIZE(key), L"Boot%04X", result->order);
|
||||||
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
|
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
|
||||||
if (size < sizeof(FFEfiLoadOption) || size == ARRAY_SIZE(buffer))
|
if (size < sizeof(FFEfiLoadOption) || size == ARRAY_SIZE(buffer))
|
||||||
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
|
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ typedef struct FFBrightnessResult
|
|||||||
{
|
{
|
||||||
FFstrbuf name;
|
FFstrbuf name;
|
||||||
double min, max, current;
|
double min, max, current;
|
||||||
|
bool builtin;
|
||||||
} FFBrightnessResult;
|
} FFBrightnessResult;
|
||||||
|
|
||||||
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result); // list of FFBrightnessResult
|
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result); // list of FFBrightnessResult
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
|
|||||||
brightness->max = 1;
|
brightness->max = 1;
|
||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
ffStrbufInitCopy(&brightness->name, &display->name);
|
ffStrbufInitCopy(&brightness->name, &display->name);
|
||||||
|
brightness->builtin = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,6 +112,7 @@ static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult*
|
|||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
brightness->current = current;
|
brightness->current = current;
|
||||||
ffStrbufInit(&brightness->name);
|
ffStrbufInit(&brightness->name);
|
||||||
|
brightness->builtin = false;
|
||||||
|
|
||||||
uint8_t edid[128] = {};
|
uint8_t edid[128] = {};
|
||||||
if (IOAVServiceReadI2C(service, 0x50, 0x00, edid, ARRAY_SIZE(edid)) == KERN_SUCCESS)
|
if (IOAVServiceReadI2C(service, 0x50, 0x00, edid, ARRAY_SIZE(edid)) == KERN_SUCCESS)
|
||||||
@@ -179,6 +181,7 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
|
|||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
brightness->current = current;
|
brightness->current = current;
|
||||||
ffStrbufInitCopy(&brightness->name, &display->name);
|
ffStrbufInitCopy(&brightness->name, &display->name);
|
||||||
|
brightness->builtin = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
|
|||||||
brightness->max = BACKLIGHTMAXLEVELS;
|
brightness->max = BACKLIGHTMAXLEVELS;
|
||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
brightness->current = status.brightness;
|
brightness->current = status.brightness;
|
||||||
|
brightness->builtin = true;
|
||||||
|
|
||||||
struct backlight_info info;
|
struct backlight_info info;
|
||||||
if(ioctl(blfd, BACKLIGHTGETINFO, &info) == 0)
|
if(ioctl(blfd, BACKLIGHTGETINFO, &info) == 0)
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ static const char* detectWithBacklight(FFlist* result)
|
|||||||
brightness->max = ffStrbufToDouble(&buffer);
|
brightness->max = ffStrbufToDouble(&buffer);
|
||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
brightness->current = actualBrightness;
|
brightness->current = actualBrightness;
|
||||||
|
brightness->builtin = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ffStrbufSubstrBefore(&backlightDir, backlightDirLength);
|
ffStrbufSubstrBefore(&backlightDir, backlightDirLength);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
|
|||||||
// https://man.netbsd.org/NetBSD-10.1/acpiout.4#DESCRIPTION
|
// https://man.netbsd.org/NetBSD-10.1/acpiout.4#DESCRIPTION
|
||||||
char key[] = "hw.acpi.acpiout0.brightness";
|
char key[] = "hw.acpi.acpiout0.brightness";
|
||||||
char* pn = key + strlen("hw.acpi.acpiout");
|
char* pn = key + strlen("hw.acpi.acpiout");
|
||||||
|
|
||||||
for (uint32_t i = 0; i <= 9; ++i)
|
for (uint32_t i = 0; i <= 9; ++i)
|
||||||
{
|
{
|
||||||
*pn = (char) ('0' + i);
|
*pn = (char) ('0' + i);
|
||||||
@@ -20,6 +20,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
|
|||||||
brightness->max = 100;
|
brightness->max = 100;
|
||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
brightness->current = value;
|
brightness->current = value;
|
||||||
|
brightness->builtin = true;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,23 +8,35 @@
|
|||||||
|
|
||||||
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
|
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
|
||||||
{
|
{
|
||||||
FF_AUTO_CLOSE_FD int devfd = open("/dev/ttyC0", O_RDONLY);
|
char path[] = "/dev/ttyCX";
|
||||||
|
for (char i = '0'; i <= '9'; ++i) {
|
||||||
|
path[strlen("/dev/ttyC")] = i;
|
||||||
|
|
||||||
if (devfd < 0) return "open(dev/ttyC0, O_RDONLY) failed";
|
FF_AUTO_CLOSE_FD int devfd = open(path, O_RDONLY);
|
||||||
|
|
||||||
struct wsdisplay_param param = {
|
if (devfd < 0) {
|
||||||
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
|
if (errno == EACCES && i == '0')
|
||||||
};
|
return "Permission denied when opening tty device";
|
||||||
|
if (errno == ENOENT)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
|
struct wsdisplay_param param = {
|
||||||
return "ioctl(WSDISPLAYIO_GETPARAM) failed";
|
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
|
||||||
|
};
|
||||||
|
|
||||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
|
||||||
ffStrbufInitStatic(&brightness->name, "wsdisplay");
|
continue;
|
||||||
|
|
||||||
brightness->max = param.max;
|
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||||
brightness->min = param.min;
|
ffStrbufInitF(&brightness->name, "ttyC%c", i);
|
||||||
brightness->current = param.curval;
|
|
||||||
|
brightness->max = param.max;
|
||||||
|
brightness->min = param.min;
|
||||||
|
brightness->current = param.curval;
|
||||||
|
brightness->builtin = true;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ static const char* detectWithWmi(FFlist* result)
|
|||||||
brightness->max = 100;
|
brightness->max = 100;
|
||||||
brightness->min = 0;
|
brightness->min = 0;
|
||||||
brightness->current = vtValue.get<uint8_t>();
|
brightness->current = vtValue.get<uint8_t>();
|
||||||
|
brightness->builtin = true;
|
||||||
|
|
||||||
ffStrbufInit(&brightness->name);
|
ffStrbufInit(&brightness->name);
|
||||||
if (FFWmiVariant vtName = record.get(L"InstanceName"))
|
if (FFWmiVariant vtName = record.get(L"InstanceName"))
|
||||||
@@ -42,6 +43,7 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
|
|||||||
FF_LIBRARY_LOAD(dxva2, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
|
FF_LIBRARY_LOAD(dxva2, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetPhysicalMonitorsFromHMONITOR)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetPhysicalMonitorsFromHMONITOR)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetMonitorBrightness)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetMonitorBrightness)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, DestroyPhysicalMonitor)
|
||||||
|
|
||||||
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
||||||
{
|
{
|
||||||
@@ -61,7 +63,10 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
|
|||||||
brightness->max = max;
|
brightness->max = max;
|
||||||
brightness->min = min;
|
brightness->min = min;
|
||||||
brightness->current = curr;
|
brightness->current = curr;
|
||||||
|
brightness->builtin = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffDestroyPhysicalMonitor(physicalMonitor.hPhysicalMonitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ static const char* enumerateDevices(FFBtrfsResult* item, int dfd, FFstrbuf* buff
|
|||||||
|
|
||||||
FF_AUTO_CLOSE_DIR DIR* dirp = fdopendir(subfd);
|
FF_AUTO_CLOSE_DIR DIR* dirp = fdopendir(subfd);
|
||||||
if(dirp == NULL)
|
if(dirp == NULL)
|
||||||
|
{
|
||||||
|
close(subfd);
|
||||||
return "fdopendir(\"/sys/fs/btrfs/UUID/devices\") == NULL";
|
return "fdopendir(\"/sys/fs/btrfs/UUID/devices\") == NULL";
|
||||||
|
}
|
||||||
|
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
while ((entry = readdir(dirp)) != NULL)
|
while ((entry = readdir(dirp)) != NULL)
|
||||||
|
|||||||
@@ -16,18 +16,18 @@ const char* ffDetectCamera(FFlist* result)
|
|||||||
#ifdef MAC_OS_X_VERSION_10_15
|
#ifdef MAC_OS_X_VERSION_10_15
|
||||||
FF_SUPPRESS_IO(); // #822
|
FF_SUPPRESS_IO(); // #822
|
||||||
|
|
||||||
AVCaptureDeviceType deviceType;
|
AVCaptureDeviceType deviceType = NULL;
|
||||||
|
|
||||||
#ifdef MAC_OS_VERSION_14_0
|
#ifdef MAC_OS_VERSION_14_0
|
||||||
|
// Strangely `@available(macOS 14.0, *)` doesn't work here (#1594)
|
||||||
if (@available(macOS 14.0, *))
|
if (@available(macOS 14.0, *))
|
||||||
{
|
{
|
||||||
deviceType = AVCaptureDeviceTypeExternal;
|
if (&AVCaptureDeviceTypeExternal)
|
||||||
|
deviceType = AVCaptureDeviceTypeExternal;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
if (deviceType == NULL)
|
||||||
deviceType = AVCaptureDeviceTypeExternalUnknown;
|
deviceType = AVCaptureDeviceTypeExternalUnknown;
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, deviceType]
|
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera, deviceType]
|
||||||
mediaType:AVMediaTypeVideo
|
mediaType:AVMediaTypeVideo
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const char* ffDetectCamera(FFlist* result)
|
|||||||
{
|
{
|
||||||
case V4L2_COLORSPACE_SMPTE170M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 170M"); break;
|
case V4L2_COLORSPACE_SMPTE170M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 170M"); break;
|
||||||
case V4L2_COLORSPACE_SMPTE240M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 240M"); break;
|
case V4L2_COLORSPACE_SMPTE240M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 240M"); break;
|
||||||
case V4L2_COLORSPACE_BT878: ffStrbufInitStatic(&camera->colorspace, "BT.808"); break;
|
case V4L2_COLORSPACE_BT878: ffStrbufInitStatic(&camera->colorspace, "BT.878"); break;
|
||||||
case V4L2_COLORSPACE_470_SYSTEM_M: ffStrbufInitStatic(&camera->colorspace, "NTSC"); break;
|
case V4L2_COLORSPACE_470_SYSTEM_M: ffStrbufInitStatic(&camera->colorspace, "NTSC"); break;
|
||||||
case V4L2_COLORSPACE_470_SYSTEM_BG: ffStrbufInitStatic(&camera->colorspace, "EBU 3213"); break;
|
case V4L2_COLORSPACE_470_SYSTEM_BG: ffStrbufInitStatic(&camera->colorspace, "EBU 3213"); break;
|
||||||
case V4L2_COLORSPACE_JPEG: ffStrbufInitStatic(&camera->colorspace, "JPEG"); break;
|
case V4L2_COLORSPACE_JPEG: ffStrbufInitStatic(&camera->colorspace, "JPEG"); break;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < count; i++)
|
for (uint32_t i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
IMFActivate* device = devices[i];
|
IMFActivate* FF_AUTO_RELEASE_COM_OBJECT device = devices[i];
|
||||||
|
|
||||||
wchar_t buffer[256];
|
wchar_t buffer[256];
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
@@ -90,9 +90,11 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Assume first type is the maximum resolution
|
// Assume first type is the maximum resolution
|
||||||
IMFMediaType* FF_AUTO_RELEASE_COM_OBJECT type = NULL;
|
IMFMediaType* type = NULL;
|
||||||
for (DWORD idx = 0; SUCCEEDED(handler->GetMediaTypeByIndex(idx, &type)); ++idx)
|
for (DWORD idx = 0; SUCCEEDED(handler->GetMediaTypeByIndex(idx, &type)); ++idx)
|
||||||
{
|
{
|
||||||
|
on_scope_exit destroyType([=] { type->Release(); });
|
||||||
|
|
||||||
GUID majorType;
|
GUID majorType;
|
||||||
if (FAILED(type->GetMajorType(&majorType)) || majorType != MFMediaType_Video)
|
if (FAILED(type->GetMajorType(&majorType)) || majorType != MFMediaType_Video)
|
||||||
continue;
|
continue;
|
||||||
@@ -123,7 +125,7 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CoTaskMemFree(devices);
|
if (devices) CoTaskMemFree(devices);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const char* ffChassisTypeToString(uint32_t type)
|
|||||||
case 0x1A: return "Compact PCI";
|
case 0x1A: return "Compact PCI";
|
||||||
case 0x1B: return "Advanced TCA";
|
case 0x1B: return "Advanced TCA";
|
||||||
case 0x1C: return "Blade";
|
case 0x1C: return "Blade";
|
||||||
|
case 0x1D: return "Mobile Workstation";
|
||||||
case 0x1E: return "Tablet";
|
case 0x1E: return "Tablet";
|
||||||
case 0x1F: return "Convertible";
|
case 0x1F: return "Convertible";
|
||||||
case 0x20: return "Detachable";
|
case 0x20: return "Detachable";
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include "chassis.h"
|
||||||
|
#include "detection/host/host.h"
|
||||||
|
|
||||||
|
const char* ffDetectChassis(FFChassisResult* result)
|
||||||
|
{
|
||||||
|
FFHostResult host = {
|
||||||
|
.family = ffStrbufCreate(),
|
||||||
|
.name = ffStrbufCreate(),
|
||||||
|
.version = ffStrbufCreate(),
|
||||||
|
.sku = ffStrbufCreate(),
|
||||||
|
.serial = ffStrbufCreate(),
|
||||||
|
.uuid = ffStrbufCreate(),
|
||||||
|
.vendor = ffStrbufCreate(),
|
||||||
|
};
|
||||||
|
if (ffDetectHost(&host) != NULL)
|
||||||
|
return "Failed to detect host";
|
||||||
|
|
||||||
|
if (ffStrbufStartsWithS(&host.name, "MacBook "))
|
||||||
|
ffStrbufSetStatic(&result->type, "Laptop");
|
||||||
|
else if (ffStrbufStartsWithS(&host.name, "Mac mini ") ||
|
||||||
|
ffStrbufStartsWithS(&host.name, "Mac Studio "))
|
||||||
|
ffStrbufSetStatic(&result->type, "Mini PC");
|
||||||
|
else if (ffStrbufStartsWithS(&host.name, "iMac "))
|
||||||
|
ffStrbufSetStatic(&result->type, "All in One");
|
||||||
|
else
|
||||||
|
ffStrbufSetStatic(&result->type, "Desktop");
|
||||||
|
|
||||||
|
ffStrbufSet(&result->vendor, &host.vendor);
|
||||||
|
|
||||||
|
ffStrbufDestroy(&host.family);
|
||||||
|
ffStrbufDestroy(&host.name);
|
||||||
|
ffStrbufDestroy(&host.version);
|
||||||
|
ffStrbufDestroy(&host.sku);
|
||||||
|
ffStrbufDestroy(&host.serial);
|
||||||
|
ffStrbufDestroy(&host.uuid);
|
||||||
|
ffStrbufDestroy(&host.vendor);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#include "cpu.h"
|
||||||
|
#include "util/mallocHelper.h"
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <private/shared/cpu_type.h>
|
||||||
|
|
||||||
|
const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPUResult* cpu)
|
||||||
|
{
|
||||||
|
system_info sysInfo;
|
||||||
|
if (get_system_info(&sysInfo) != B_OK)
|
||||||
|
return "get_system_info() failed";
|
||||||
|
|
||||||
|
uint32 topoNodeCount = 0;
|
||||||
|
get_cpu_topology_info(NULL, &topoNodeCount);
|
||||||
|
if (topoNodeCount == 0)
|
||||||
|
return "get_cpu_topology_info(NULL) failed";
|
||||||
|
|
||||||
|
FF_AUTO_FREE cpu_topology_node_info* topology = malloc(sizeof(*topology) * topoNodeCount);
|
||||||
|
if (get_cpu_topology_info(topology, &topoNodeCount) != B_OK)
|
||||||
|
return "get_cpu_topology_info(topology) failed";
|
||||||
|
|
||||||
|
enum cpu_platform platform = B_CPU_UNKNOWN;
|
||||||
|
enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN;
|
||||||
|
uint32 cpuModel = 0, frequency = 0;
|
||||||
|
uint16_t packages = 0, cores = 0;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < topoNodeCount; i++)
|
||||||
|
{
|
||||||
|
switch (topology[i].type) {
|
||||||
|
case B_TOPOLOGY_ROOT:
|
||||||
|
platform = topology[i].data.root.platform;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_TOPOLOGY_PACKAGE:
|
||||||
|
cpuVendor = topology[i].data.package.vendor;
|
||||||
|
++packages;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_TOPOLOGY_CORE:
|
||||||
|
cpuModel = topology[i].data.core.model;
|
||||||
|
uint32_t freq = (uint32_t) (topology[i].data.core.default_frequency / 1000000);
|
||||||
|
frequency = freq > frequency ? freq : frequency;
|
||||||
|
++cores;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *model = get_cpu_model_string(platform, cpuVendor, cpuModel);
|
||||||
|
if (model)
|
||||||
|
ffStrbufSetS(&cpu->name, model);
|
||||||
|
else
|
||||||
|
ffStrbufSetF(&cpu->name, "(Unknown %" B_PRIx32 ")", cpuModel);
|
||||||
|
ffStrbufSetS(&cpu->vendor, get_cpu_vendor_string(cpuVendor));
|
||||||
|
|
||||||
|
ffCPUDetectSpeedByCpuid(cpu);
|
||||||
|
if (cpu->frequencyBase < frequency) cpu->frequencyBase = frequency;
|
||||||
|
cpu->packages = packages;
|
||||||
|
cpu->coresPhysical = cores;
|
||||||
|
cpu->coresOnline = cpu->coresLogical = (uint16_t) sysInfo.cpu_count;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -430,7 +430,6 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
|
|||||||
|
|
||||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
|
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
|
||||||
{
|
{
|
||||||
if (!p) break;
|
|
||||||
p += strlen("\nphysical id\t:");
|
p += strlen("\nphysical id\t:");
|
||||||
char* pend;
|
char* pend;
|
||||||
unsigned long id = strtoul(p, &pend, 10);
|
unsigned long id = strtoul(p, &pend, 10);
|
||||||
@@ -586,7 +585,6 @@ FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const c
|
|||||||
|
|
||||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), key, keylen)))
|
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), key, keylen)))
|
||||||
{
|
{
|
||||||
if (!p) break;
|
|
||||||
p += keylen;
|
p += keylen;
|
||||||
char* pend;
|
char* pend;
|
||||||
unsigned long id = strtoul(p, &pend, 10);
|
unsigned long id = strtoul(p, &pend, 10);
|
||||||
@@ -608,7 +606,7 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options,
|
|||||||
|
|
||||||
#if __ANDROID__
|
#if __ANDROID__
|
||||||
detectAndroid(cpu);
|
detectAndroid(cpu);
|
||||||
#else
|
#elif !__powerpc__ && !__powerpc
|
||||||
detectSocName(cpu);
|
detectSocName(cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,19 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
static void freePropDict(prop_dictionary_t* pdict)
|
||||||
|
{
|
||||||
|
assert(pdict != NULL);
|
||||||
|
if (*pdict == NULL) return;
|
||||||
|
prop_object_release(*pdict);
|
||||||
|
}
|
||||||
|
|
||||||
static const char* detectCpuTemp(double* current)
|
static const char* detectCpuTemp(double* current)
|
||||||
{
|
{
|
||||||
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
|
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
|
||||||
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
|
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
|
||||||
|
|
||||||
prop_dictionary_t root = NULL;
|
__attribute__((__cleanup__(freePropDict))) prop_dictionary_t root = NULL;
|
||||||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
|
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
|
||||||
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
||||||
|
|
||||||
@@ -42,10 +49,11 @@ static const char* detectCpuTemp(double* current)
|
|||||||
|
|
||||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||||
{
|
{
|
||||||
if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != NULL)
|
if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != NULL &&
|
||||||
|
ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != NULL &&
|
||||||
|
ffSysctlGetString("hw.cpu0.name", &cpu->name) != NULL)
|
||||||
{
|
{
|
||||||
if (ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != NULL)
|
ffStrbufSetS(&cpu->name, "Unknown CPU");
|
||||||
return "sysctlbyname(machdep.cpu_brand) failed";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL)
|
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL)
|
||||||
@@ -58,6 +66,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
|||||||
ffCPUDetectSpeedByCpuid(cpu);
|
ffCPUDetectSpeedByCpuid(cpu);
|
||||||
|
|
||||||
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
|
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
|
||||||
|
if (freq == 0) freq = (uint32_t) (ffSysctlGetInt64("hw.cpu0.clock_frequency", 0) / 1000000);
|
||||||
if (freq > cpu->frequencyBase) cpu->frequencyBase = freq;
|
if (freq > cpu->frequencyBase) cpu->frequencyBase = freq;
|
||||||
|
|
||||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||||
|
|||||||
@@ -23,22 +23,24 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
|
|||||||
|
|
||||||
{
|
{
|
||||||
kstat_named_t* kn = kstat_data_lookup(ks, "brand");
|
kstat_named_t* kn = kstat_data_lookup(ks, "brand");
|
||||||
ffStrbufSetNS(&cpu->name, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
if (kn) ffStrbufSetNS(&cpu->name, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
||||||
ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
if (kn) ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||||
}
|
}
|
||||||
ffCPUDetectSpeedByCpuid(cpu);
|
ffCPUDetectSpeedByCpuid(cpu);
|
||||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
{
|
||||||
if (kn->value.ui32 > cpu->frequencyBase)
|
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||||
cpu->frequencyBase = kn->value.ui32;
|
if (kn && kn->value.ui32 > cpu->frequencyBase)
|
||||||
|
cpu->frequencyBase = kn->value.ui32;
|
||||||
|
}
|
||||||
|
|
||||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||||
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
||||||
{
|
{
|
||||||
kstat_named_t* kn = kstat_data_lookup(ks, "ncpus");
|
kstat_named_t* kn = kstat_data_lookup(ks, "ncpus");
|
||||||
cpu->coresLogical = cpu->coresPhysical = cpu->coresOnline = (uint16_t) kn->value.ui32;
|
if (kn) cpu->coresLogical = cpu->coresPhysical = cpu->coresOnline = (uint16_t) kn->value.ui32;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -128,9 +128,13 @@ static const char* detectByRegistry(FFCPUResult* cpu)
|
|||||||
|
|
||||||
if (cpu->coresLogical == 0)
|
if (cpu->coresLogical == 0)
|
||||||
{
|
{
|
||||||
DWORD cores;
|
FF_HKEY_AUTO_DESTROY hProcsKey = NULL;
|
||||||
if (RegQueryInfoKeyW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", NULL, NULL, &cores, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", &hProcsKey, NULL))
|
||||||
cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores;
|
{
|
||||||
|
uint32_t cores;
|
||||||
|
if (ffRegGetNSubKeys(hProcsKey, &cores, NULL))
|
||||||
|
cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mhz;
|
uint32_t mhz;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ const char* detectThermalTemp(double* current, double* critical)
|
|||||||
else
|
else
|
||||||
*critical = 0.0/0.0;
|
*critical = 0.0/0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "No WMI result returned";
|
return "No WMI result returned";
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result)
|
|||||||
case CacheInstruction: cacheType = FF_CPU_CACHE_TYPE_INSTRUCTION; break;
|
case CacheInstruction: cacheType = FF_CPU_CACHE_TYPE_INSTRUCTION; break;
|
||||||
case CacheData: cacheType = FF_CPU_CACHE_TYPE_DATA; break;
|
case CacheData: cacheType = FF_CPU_CACHE_TYPE_DATA; break;
|
||||||
case CacheTrace: cacheType = FF_CPU_CACHE_TYPE_TRACE; break;
|
case CacheTrace: cacheType = FF_CPU_CACHE_TYPE_TRACE; break;
|
||||||
default: __builtin_unreachable(); break;
|
default: break;
|
||||||
}
|
}
|
||||||
ffCPUCacheAddItem(result, ptr->Cache.Level, ptr->Cache.CacheSize, ptr->Cache.LineSize, cacheType);
|
ffCPUCacheAddItem(result, ptr->Cache.Level, ptr->Cache.CacheSize, ptr->Cache.LineSize, cacheType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <mach/processor_info.h>
|
#include <mach/processor_info.h>
|
||||||
#include <mach/mach_host.h>
|
#include <mach/mach_host.h>
|
||||||
|
#include <mach/vm_map.h>
|
||||||
|
|
||||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||||
{
|
{
|
||||||
@@ -28,5 +29,7 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
|||||||
.totalAll = (uint64_t)total,
|
.totalAll = (uint64_t)total,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm_deallocate(mach_task_self(), (vm_address_t) cpuInfo, numCpuInfo * sizeof(integer_t));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#include "fastfetch.h"
|
||||||
|
#include "detection/cpuusage/cpuusage.h"
|
||||||
|
#include "util/mallocHelper.h"
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||||
|
{
|
||||||
|
system_info sysInfo;
|
||||||
|
if (get_system_info(&sysInfo) != B_OK)
|
||||||
|
return "get_system_info() failed";
|
||||||
|
|
||||||
|
FF_AUTO_FREE cpu_info* cpuInfo = malloc(sizeof(*cpuInfo) * sysInfo.cpu_count);
|
||||||
|
if (get_cpu_info(0, sysInfo.cpu_count, cpuInfo) != B_OK)
|
||||||
|
return "get_cpu_info() failed";
|
||||||
|
|
||||||
|
uint64_t uptime = (uint64_t) system_time();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sysInfo.cpu_count; ++i)
|
||||||
|
{
|
||||||
|
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||||
|
info->inUseAll = (uint64_t) cpuInfo[i].active_time;
|
||||||
|
info->totalAll = uptime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
|
|||||||
return "geom_gettree() failed";
|
return "geom_gettree() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cLabels = geomTree.lg_class.lh_first; !ffStrEquals(cLabels->lg_name, "LABEL"); cLabels = cLabels->lg_class.le_next);
|
for (cLabels = geomTree.lg_class.lh_first; cLabels && !ffStrEquals(cLabels->lg_name, "LABEL"); cLabels = cLabels->lg_class.le_next);
|
||||||
if (!cLabels)
|
if (!cLabels)
|
||||||
return "Class LABEL is not found";
|
return "Class LABEL is not found";
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
|||||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||||
|
|
||||||
disk->filesTotal = (uint32_t) fs->f_files;
|
disk->filesTotal = (uint32_t) fs->f_files;
|
||||||
disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree);
|
disk->filesUsed = (uint32_t) (fs->f_files - fs->f_ffree);
|
||||||
|
|
||||||
ffStrbufInitS(&disk->mountFrom, fs->f_mntfromname);
|
ffStrbufInitS(&disk->mountFrom, fs->f_mntfromname);
|
||||||
ffStrbufInitS(&disk->mountpoint, fs->f_mntonname);
|
ffStrbufInitS(&disk->mountpoint, fs->f_mntonname);
|
||||||
@@ -185,7 +185,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
|||||||
#ifndef __DragonFly__
|
#ifndef __DragonFly__
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
|
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
|
||||||
disk->createTime = (uint64_t)((st.st_birthtimespec.tv_sec * 1000) + (st.st_birthtimespec.tv_nsec / 1000000));
|
disk->createTime = (uint64_t)(((uint64_t) st.st_birthtimespec.tv_sec * 1000) + ((uint64_t) st.st_birthtimespec.tv_nsec / 1000000));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include "disk.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
}
|
||||||
|
#include <fs_info.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||||
|
{
|
||||||
|
int32 pos = 0;
|
||||||
|
|
||||||
|
for (dev_t dev; (dev = next_dev(&pos)) >= B_OK;)
|
||||||
|
{
|
||||||
|
fs_info fs;
|
||||||
|
if (fs_stat_dev(dev, &fs) < 0) continue;
|
||||||
|
|
||||||
|
node_ref node(fs.dev, fs.root);
|
||||||
|
BDirectory dir(&node);
|
||||||
|
BPath path(&dir);
|
||||||
|
if (path.InitCheck() != B_OK) continue;
|
||||||
|
|
||||||
|
if (__builtin_expect(options->folders.length, 0))
|
||||||
|
{
|
||||||
|
if (!ffDiskMatchMountpoint(options, path.Path()))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FFDisk* disk = (FFDisk*) ffListAdd(disks);
|
||||||
|
|
||||||
|
disk->bytesTotal = (uint64_t)fs.total_blocks * (uint64_t) fs.block_size;
|
||||||
|
disk->bytesFree = (uint64_t)fs.free_blocks * (uint64_t) fs.block_size;
|
||||||
|
disk->bytesAvailable = disk->bytesFree;
|
||||||
|
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||||
|
|
||||||
|
disk->filesTotal = (uint32_t) fs.total_nodes;
|
||||||
|
disk->filesUsed = (uint32_t) (fs.total_nodes - fs.free_nodes);
|
||||||
|
|
||||||
|
ffStrbufInitS(&disk->mountFrom, fs.device_name);
|
||||||
|
ffStrbufInitS(&disk->mountpoint, path.Path());
|
||||||
|
ffStrbufInitS(&disk->filesystem, fs.fsh_name);
|
||||||
|
ffStrbufInitS(&disk->name, fs.volume_name);
|
||||||
|
disk->type = FF_DISK_VOLUME_TYPE_NONE;
|
||||||
|
if (!(fs.flags & B_FS_IS_PERSISTENT))
|
||||||
|
disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
|
||||||
|
if (fs.flags & B_FS_IS_READONLY)
|
||||||
|
disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_READONLY_BIT);
|
||||||
|
if (fs.flags & B_FS_IS_REMOVABLE)
|
||||||
|
disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
|
||||||
|
if (disk->type == FF_DISK_VOLUME_TYPE_NONE) disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||||
|
disk->createTime = 0;
|
||||||
|
|
||||||
|
time_t crTime;
|
||||||
|
if (dir.GetCreationTime(&crTime) == B_OK)
|
||||||
|
disk->createTime = (uint64_t) crTime * 1000;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -209,7 +209,10 @@ static bool isRemovable(FFDisk* currentDisk)
|
|||||||
char sysBlockVolume[PATH_MAX]; // /sys/devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
char sysBlockVolume[PATH_MAX]; // /sys/devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||||
if (realpath(sysBlockPartition, sysBlockVolume) == NULL)
|
if (realpath(sysBlockPartition, sysBlockVolume) == NULL)
|
||||||
return false;
|
return false;
|
||||||
strcpy(strrchr(sysBlockVolume, '/') + 1, "removable");
|
char* lastSlash = strrchr(sysBlockVolume, '/');
|
||||||
|
if (lastSlash == NULL)
|
||||||
|
return false;
|
||||||
|
strcpy(lastSlash + 1, "removable");
|
||||||
|
|
||||||
char removableChar = '0';
|
char removableChar = '0';
|
||||||
return ffReadFileData(sysBlockVolume, 1, &removableChar) > 0 && removableChar == '1';
|
return ffReadFileData(sysBlockVolume, 1, &removableChar) > 0 && removableChar == '1';
|
||||||
|
|||||||
@@ -99,9 +99,6 @@ static void detectStats(FFDisk* disk)
|
|||||||
ffStrbufSetS(&disk->name, fs.f_fstr);
|
ffStrbufSetS(&disk->name, fs.f_fstr);
|
||||||
|
|
||||||
disk->createTime = 0;
|
disk->createTime = 0;
|
||||||
struct stat deviceStat;
|
|
||||||
if(stat(disk->mountpoint.chars, &deviceStat) == 0)
|
|
||||||
disk->createTime = (uint64_t) deviceStat.st_ctim.tv_sec * 1000 + (uint64_t) deviceStat.st_ctim.tv_nsec / 1000000000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||||
|
|||||||
@@ -69,10 +69,15 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
|
|||||||
uint64_t temp = *currValue;
|
uint64_t temp = *currValue;
|
||||||
*currValue -= *prevValue;
|
*currValue -= *prevValue;
|
||||||
*currValue /= (time2 - time1) / 1000 /* seconds */;
|
*currValue /= (time2 - time1) / 1000 /* seconds */;
|
||||||
|
|
||||||
|
// For next function call
|
||||||
*prevValue = temp;
|
*prevValue = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For next function call
|
||||||
time1 = time2;
|
time1 = time2;
|
||||||
|
// Leak ioCounters1 here
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||||
{
|
{
|
||||||
struct gmesh geomTree;
|
__attribute__((__cleanup__(geom_deletetree)))
|
||||||
|
struct gmesh geomTree = {};
|
||||||
if (geom_gettree(&geomTree) < 0)
|
if (geom_gettree(&geomTree) < 0)
|
||||||
return "geom_gettree() failed";
|
return "geom_gettree() failed";
|
||||||
|
|
||||||
@@ -21,6 +22,9 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
return "geom_stats_open() failed";
|
return "geom_stats_open() failed";
|
||||||
|
|
||||||
void* snap = geom_stats_snapshot_get();
|
void* snap = geom_stats_snapshot_get();
|
||||||
|
if (!snap)
|
||||||
|
return "geom_stats_snapshot_get() failed";
|
||||||
|
|
||||||
struct devstat* snapIter;
|
struct devstat* snapIter;
|
||||||
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
|
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FFDiskIOOptions* options)
|
static const char* parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FFDiskIOOptions* options)
|
||||||
{
|
{
|
||||||
FF_AUTO_CLOSE_FD int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
FF_AUTO_CLOSE_FD int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
||||||
if (devfd < 0) return; // virtual device
|
if (devfd < 0) return "virtual device";
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FF
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||||
return;
|
return "ignored";
|
||||||
}
|
}
|
||||||
|
|
||||||
// I/Os merges sectors ticks ...
|
// I/Os merges sectors ticks ...
|
||||||
@@ -57,10 +57,10 @@ static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FF
|
|||||||
{
|
{
|
||||||
char sysBlockStat[PROC_FILE_BUFFSIZ];
|
char sysBlockStat[PROC_FILE_BUFFSIZ];
|
||||||
ssize_t fileSize = ffReadFileDataRelative(dfd, "stat", ARRAY_SIZE(sysBlockStat) - 1, sysBlockStat);
|
ssize_t fileSize = ffReadFileDataRelative(dfd, "stat", ARRAY_SIZE(sysBlockStat) - 1, sysBlockStat);
|
||||||
if (fileSize <= 0) return;
|
if (fileSize <= 0) return "failed to read stat file";
|
||||||
sysBlockStat[fileSize] = '\0';
|
sysBlockStat[fileSize] = '\0';
|
||||||
if (sscanf(sysBlockStat, "%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0)
|
if (sscanf(sysBlockStat, "%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0)
|
||||||
return;
|
return "invalid stat file format";
|
||||||
}
|
}
|
||||||
|
|
||||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||||
@@ -70,6 +70,8 @@ static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FF
|
|||||||
device->bytesWritten = sectorWritten * 512;
|
device->bytesWritten = sectorWritten * 512;
|
||||||
device->readCount = nRead;
|
device->readCount = nRead;
|
||||||
device->writeCount = nWritten;
|
device->writeCount = nWritten;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||||
@@ -83,7 +85,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
{
|
{
|
||||||
const char* const devName = sysBlockEntry->d_name;
|
const char* const devName = sysBlockEntry->d_name;
|
||||||
|
|
||||||
if (devName[0] == '.') continue;;
|
if (devName[0] == '.') continue;
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
||||||
if (dfd > 0) parseDiskIOCounters(dfd, devName, result, options);
|
if (dfd > 0) parseDiskIOCounters(dfd, devName, result, options);
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0)
|
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0)
|
||||||
return "sysctl({HW_IOSTATS}, NULL) failed";
|
return "sysctl({HW_IOSTATS}, NULL) failed";
|
||||||
uint32_t nDrive = (uint32_t) (len / sizeof(struct io_sysctl));
|
uint32_t nDrive = (uint32_t) (len / sizeof(struct io_sysctl));
|
||||||
|
|
||||||
struct io_sysctl* stats = malloc(len);
|
FF_AUTO_FREE struct io_sysctl* stats = malloc(len);
|
||||||
|
|
||||||
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
||||||
return "sysctl({HW_IOSTATS}, stats) failed";
|
return "sysctl({HW_IOSTATS}, stats) failed";
|
||||||
|
|
||||||
for (uint32_t i = 0; i < nDrive; ++i)
|
for (uint32_t i = 0; i < nDrive; ++i)
|
||||||
{
|
{
|
||||||
struct io_sysctl* st = &stats[i];
|
struct io_sysctl* st = &stats[i];
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
return "sysctl({HW_DISKSTATS}, NULL) failed";
|
return "sysctl({HW_DISKSTATS}, NULL) failed";
|
||||||
uint32_t nDrive = (uint32_t) (len / sizeof(struct diskstats));
|
uint32_t nDrive = (uint32_t) (len / sizeof(struct diskstats));
|
||||||
|
|
||||||
struct diskstats* stats = malloc(len);
|
FF_AUTO_FREE struct diskstats* stats = malloc(len);
|
||||||
|
|
||||||
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
||||||
return "sysctl({HW_DISKSTATS}, stats) failed";
|
return "sysctl({HW_DISKSTATS}, stats) failed";
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||||
ffStrbufInit(&device->devPath);
|
ffStrbufInit(&device->devPath); // unlike other platforms, `/dev/ks_name` is not available
|
||||||
ffStrbufInitS(&device->name, ks->ks_name);
|
ffStrbufInitS(&device->name, ks->ks_name);
|
||||||
device->bytesRead = kio.nread;
|
device->bytesRead = kio.nread;
|
||||||
device->readCount = kio.reads;
|
device->readCount = kio.reads;
|
||||||
|
|||||||
@@ -56,8 +56,6 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFDiskIO
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufInitWS(&device->devPath, szDevice);
|
|
||||||
|
|
||||||
DISK_PERFORMANCE dp = {};
|
DISK_PERFORMANCE dp = {};
|
||||||
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
|
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
|
||||||
{
|
{
|
||||||
@@ -72,6 +70,8 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFDiskIO
|
|||||||
result->length--;
|
result->length--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffStrbufInitWS(&device->devPath, szDevice);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,33 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
static bool checkHdrStatus(FFDisplayResult* display)
|
||||||
|
{
|
||||||
|
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||||
|
|
||||||
|
if (ffSettingsGetAndroidProperty("ro.surface_flinger.has_HDR_display", &buffer))
|
||||||
|
{
|
||||||
|
if (ffStrbufIgnCaseEqualS(&buffer, "true"))
|
||||||
|
{
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
|
||||||
|
|
||||||
|
if (ffSettingsGetAndroidProperty("persist.sys.hdr_mode", &buffer) &&
|
||||||
|
ffStrbufToUInt(&buffer, 0) > 0)
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void detectWithDumpsys(FFDisplayServerResult* ds)
|
static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||||
{
|
{
|
||||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||||
@@ -54,7 +81,7 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufRecalculateLength(&name);
|
ffStrbufRecalculateLength(&name);
|
||||||
ffdsAppendDisplay(ds,
|
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||||
(uint32_t)width,
|
(uint32_t)width,
|
||||||
(uint32_t)height,
|
(uint32_t)height,
|
||||||
refreshRate,
|
refreshRate,
|
||||||
@@ -72,6 +99,7 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
|
|||||||
0,
|
0,
|
||||||
"dumpsys"
|
"dumpsys"
|
||||||
);
|
);
|
||||||
|
if (display) display->hdrStatus = checkHdrStatus(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
index = nextIndex + 1;
|
index = nextIndex + 1;
|
||||||
@@ -92,7 +120,7 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
|||||||
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||||
ffStrbufSubstrAfterFirstC(&buffer, ',');
|
ffStrbufSubstrAfterFirstC(&buffer, ',');
|
||||||
double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.;
|
double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.;
|
||||||
return ffdsAppendDisplay(ds,
|
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
0,
|
0,
|
||||||
@@ -110,6 +138,8 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
|||||||
0,
|
0,
|
||||||
"getprop"
|
"getprop"
|
||||||
);
|
);
|
||||||
|
if (display) display->hdrStatus = checkHdrStatus(display);
|
||||||
|
return !!display;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
|||||||
if(displayInfo)
|
if(displayInfo)
|
||||||
{
|
{
|
||||||
CFDictionaryRef productNames;
|
CFDictionaryRef productNames;
|
||||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
if(ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames) == NULL)
|
||||||
ffCfDictGetString(productNames, CFSTR("en_US"), &buffer);
|
ffCfDictGetString(productNames, CFSTR("en_US"), &buffer);
|
||||||
|
|
||||||
// CGDisplayScreenSize reports invalid result for external displays on old Intel MacBook Pro
|
// CGDisplayScreenSize reports invalid result for external displays on old Intel MacBook Pro
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#include "displayserver.h"
|
#include "displayserver.h"
|
||||||
#include "common/settings.h"
|
|
||||||
#include "common/processing.h"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -31,14 +29,16 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
|||||||
monitor_info monitor;
|
monitor_info monitor;
|
||||||
// WARNING: This is experimental new Haiku API
|
// WARNING: This is experimental new Haiku API
|
||||||
status_t err = s.GetMonitorInfo(&monitor);
|
status_t err = s.GetMonitorInfo(&monitor);
|
||||||
if (err == B_OK) {
|
if (err == B_OK)
|
||||||
|
{
|
||||||
ffStrbufSetF(&name, "%s %s", monitor.vendor, monitor.name);
|
ffStrbufSetF(&name, "%s %s", monitor.vendor, monitor.name);
|
||||||
|
ffStrbufTrimRightSpace(&name);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t width = (uint32_t) s.Frame().Width() + 1;
|
uint32_t width = (uint32_t) s.Frame().Width() + 1;
|
||||||
uint32_t height = (uint32_t) (uint32_t)s.Frame().Height() + 1;
|
uint32_t height = (uint32_t) (uint32_t)s.Frame().Height() + 1;
|
||||||
double scaleFactor = (double) 1.0;
|
double scaleFactor = (double) 1.0;
|
||||||
ffdsAppendDisplay(ds,
|
FFDisplayResult* res = ffdsAppendDisplay(ds,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
(double)mode.timing.pixel_clock * 1000 / (mode.timing.v_total * mode.timing.h_total),
|
(double)mode.timing.pixel_clock * 1000 / (mode.timing.v_total * mode.timing.h_total),
|
||||||
@@ -51,11 +51,16 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
|||||||
&name,
|
&name,
|
||||||
FF_DISPLAY_TYPE_UNKNOWN,
|
FF_DISPLAY_TYPE_UNKNOWN,
|
||||||
main,
|
main,
|
||||||
s.ID().id,
|
(uint64_t) s.ID().id,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"BScreen"
|
"BScreen"
|
||||||
);
|
);
|
||||||
|
if (err == B_OK)
|
||||||
|
{
|
||||||
|
res->manufactureWeek = monitor.produced.week;
|
||||||
|
res->manufactureYear = monitor.produced.year;
|
||||||
|
}
|
||||||
main = false;
|
main = false;
|
||||||
} while (s.SetToNext() == B_OK);
|
} while (s.SetToNext() == B_OK);
|
||||||
|
|
||||||
|
|||||||
@@ -189,26 +189,47 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
|||||||
|
|
||||||
if (display)
|
if (display)
|
||||||
{
|
{
|
||||||
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
|
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO_2 advColorInfo2 = {
|
||||||
.header = {
|
.header = {
|
||||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
|
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO_2,
|
||||||
.size = sizeof(advColorInfo),
|
.size = sizeof(advColorInfo2),
|
||||||
.adapterId = path->targetInfo.adapterId,
|
.adapterId = path->targetInfo.adapterId,
|
||||||
.id = path->targetInfo.id,
|
.id = path->targetInfo.id,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
|
if (DisplayConfigGetDeviceInfo(&advColorInfo2.header) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (advColorInfo.advancedColorEnabled)
|
if (advColorInfo2.highDynamicRangeUserEnabled)
|
||||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
|
||||||
else if (advColorInfo.advancedColorSupported)
|
else if (advColorInfo2.highDynamicRangeSupported)
|
||||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
|
||||||
else
|
else
|
||||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||||
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
|
display->bitDepth = (uint8_t) advColorInfo2.bitsPerColorChannel;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
|
{
|
||||||
|
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
|
||||||
|
.header = {
|
||||||
|
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
|
||||||
|
.size = sizeof(advColorInfo),
|
||||||
|
.adapterId = path->targetInfo.adapterId,
|
||||||
|
.id = path->targetInfo.id,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (advColorInfo.advancedColorEnabled)
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
|
||||||
|
else if (advColorInfo.advancedColorSupported)
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
|
||||||
|
else
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||||
|
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
|
||||||
|
}
|
||||||
if (edidLength > 0)
|
if (edidLength > 0)
|
||||||
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
|
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
|||||||
|
|
||||||
char buf;
|
char buf;
|
||||||
ffStrbufAppendS(&drmDir, "/enabled");
|
ffStrbufAppendS(&drmDir, "/enabled");
|
||||||
if (!ffReadFileData(drmDir.chars, sizeof(buf), &buf) || buf != 'e') {
|
if (ffReadFileData(drmDir.chars, sizeof(buf), &buf) <= 0 || buf != 'e') {
|
||||||
/* read failed or enabled != "enabled" */
|
/* read failed or enabled != "enabled" */
|
||||||
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
|
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
|
||||||
ffStrbufAppendS(&drmDir, "/status");
|
ffStrbufAppendS(&drmDir, "/status");
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ const char* ffdsConnectWayland(FFDisplayServerResult* result)
|
|||||||
FF_LIST_FOR_EACH(FFstrbuf, basePath, instance.state.platform.configDirs)
|
FF_LIST_FOR_EACH(FFstrbuf, basePath, instance.state.platform.configDirs)
|
||||||
{
|
{
|
||||||
char path[1024];
|
char path[1024];
|
||||||
snprintf(path, ARRAY_SIZE(path) - 1, "%s%s", basePath->chars, fileName);
|
snprintf(path, ARRAY_SIZE(path), "%s%s", basePath->chars, fileName);
|
||||||
if (ffReadFileBuffer(path, &monitorsXml))
|
if (ffReadFileBuffer(path, &monitorsXml))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
|
|||||||
ffStrbufAppendS(&procPath, dirent->d_name);
|
ffStrbufAppendS(&procPath, dirent->d_name);
|
||||||
uint32_t procFolderPathLength = procPath.length;
|
uint32_t procFolderPathLength = procPath.length;
|
||||||
|
|
||||||
//Don't check for processes not owend by the current user.
|
//Don't check for processes not owned by the current user.
|
||||||
ffStrbufAppendS(&procPath, "/loginuid");
|
ffStrbufAppendS(&procPath, "/loginuid");
|
||||||
ffReadFileBuffer(procPath.chars, &loginuid);
|
ffReadFileBuffer(procPath.chars, &loginuid);
|
||||||
if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
|
if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ typedef struct XcbPropertyData
|
|||||||
FF_LIBRARY_SYMBOL(xcb_get_atom_name_reply)
|
FF_LIBRARY_SYMBOL(xcb_get_atom_name_reply)
|
||||||
} XcbPropertyData;
|
} XcbPropertyData;
|
||||||
|
|
||||||
static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyData)
|
static bool xcbInitPropertyData(FF_MAYBE_UNUSED void* libraryHandle, XcbPropertyData* propertyData)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom_reply, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom_reply, false)
|
||||||
@@ -333,7 +333,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
|||||||
|
|
||||||
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(xcbRandr, "dlopen lbxcb-randr failed", "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
FF_LIBRARY_LOAD(xcbRandr, "dlopen libxcb-randr failed", "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_connect)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_connect)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_get_setup)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_get_setup)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_setup_roots_iterator)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_setup_roots_iterator)
|
||||||
@@ -369,7 +369,7 @@ const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
|||||||
|
|
||||||
data.connection = ffxcb_connect(NULL, NULL);
|
data.connection = ffxcb_connect(NULL, NULL);
|
||||||
if(data.connection == NULL)
|
if(data.connection == NULL)
|
||||||
return "xcb_connect failed";
|
return "xcb_connect() failed";
|
||||||
|
|
||||||
|
|
||||||
data.result = result;
|
data.result = result;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ typedef struct X11PropertyData
|
|||||||
FF_LIBRARY_SYMBOL(XFree)
|
FF_LIBRARY_SYMBOL(XFree)
|
||||||
} X11PropertyData;
|
} X11PropertyData;
|
||||||
|
|
||||||
static bool x11InitPropertyData(void* libraryHandle, X11PropertyData* propertyData)
|
static bool x11InitPropertyData(FF_MAYBE_UNUSED void* libraryHandle, X11PropertyData* propertyData)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XInternAtom, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XInternAtom, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XGetWindowProperty, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XGetWindowProperty, false)
|
||||||
@@ -147,7 +147,7 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
|
|||||||
"xlib-randr-crtc"
|
"xlib-randr-crtc"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (edidLength)
|
if (item && edidLength)
|
||||||
{
|
{
|
||||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||||
@@ -231,7 +231,7 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen)
|
|||||||
if(monitorInfos == NULL)
|
if(monitorInfos == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool foundAMonitor;
|
bool foundAMonitor = false;
|
||||||
|
|
||||||
for(int i = 0; i < numberOfMonitors; i++)
|
for(int i = 0; i < numberOfMonitors; i++)
|
||||||
{
|
{
|
||||||
@@ -272,7 +272,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
|||||||
0,
|
0,
|
||||||
(uint32_t) WidthMMOfScreen(screen),
|
(uint32_t) WidthMMOfScreen(screen),
|
||||||
(uint32_t) HeightMMOfScreen(screen),
|
(uint32_t) HeightMMOfScreen(screen),
|
||||||
"xlib_randr_screen"
|
"xlib-randr-screen"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user