mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ede47fede | |||
| d84ae91f59 | |||
| 70160d324f | |||
| 600f6c7f24 | |||
| 11b1b97567 | |||
| 4ae0c43c6f | |||
| e89d475a3b | |||
| 4f3cd46f96 | |||
| c076f5ae98 | |||
| 064d7d3c3a | |||
| 9937eeab1d | |||
| e8326306f8 | |||
| 89bc7eb015 | |||
| 3cd81ec3ad | |||
| 0f497a53ad | |||
| 569883a1a1 | |||
| 04a41cbd6b | |||
| 4e4246a46a | |||
| c3a28064f6 | |||
| ce9f9ed7ed | |||
| fb8c7d6e4a | |||
| 70f39e641c | |||
| 1dbd8474c2 | |||
| e7c787159a | |||
| 9339a0fb4e | |||
| b692b759c7 | |||
| 529f94c64a | |||
| e071a1eeb2 | |||
| 3400e40e47 | |||
| d32125e988 | |||
| b3484088e9 | |||
| f91a8aea4d | |||
| 335022e034 | |||
| 8fa073b1e4 | |||
| 10e1753c03 | |||
| 224a6a9881 | |||
| e804dfc49e | |||
| 8048101eca | |||
| 833727f333 | |||
| 8ed5d30b3e | |||
| f62cdff924 | |||
| 25a792743b | |||
| b63e6a3053 | |||
| a565dcfb9e | |||
| 453f4757ed | |||
| 0555fb97e8 | |||
| 663d568927 | |||
| 165c213ed0 | |||
| a28dc8a9bf | |||
| f20b6d4387 | |||
| 4925222dab | |||
| 77cc0c61d7 | |||
| a19888bb33 | |||
| 40aa4a60d6 | |||
| c4824b2b5d | |||
| dcbda6c0d5 | |||
| 91e4e94aaa | |||
| 1504e26e38 | |||
| a9c5c2892c | |||
| 923997f0a2 | |||
| 0182e32f00 | |||
| bd40205427 |
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: '[BUG] '
|
||||||
labels: bug
|
labels: bug
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
@@ -24,12 +24,9 @@ The content of the configuration file you use (if any)
|
|||||||
//paste here
|
//paste here
|
||||||
```
|
```
|
||||||
|
|
||||||
Output of `env NO_CONFIG=1 fastfetch --load-config all --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false`:
|
Output of `fastfetch -c ci.jsonc --format json`:
|
||||||
<!--
|
<!--
|
||||||
Note that this output will contain you public IP. If it is not relevant for the issue, feel free to remove it before uploading.
|
Note that this output will contain you public IP. If it is not relevant for the issue, feel free to remove it before uploading.
|
||||||
|
|
||||||
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
|
|
||||||
If this isn't possible (or too much work) for you, post the output of `env NO_CONFIG=1 fastfetch --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false && fastfetch --version`.
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
---
|
---
|
||||||
name: Feature request
|
name: Feature request
|
||||||
about: Suggest an idea for this project
|
about: Suggest an idea for this project
|
||||||
title: ''
|
title: '[FEAT] '
|
||||||
labels: enhancement
|
labels: enhancement
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!-- Before requesting a new feature, please try `fastfetch -c all.jsonc` to see if it has been supported -->
|
||||||
|
|
||||||
# Current state:
|
# Current state:
|
||||||
|
|
||||||
# Wanted state:
|
# Wanted state:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: Logo request
|
name: Logo request
|
||||||
about: Request a new logo
|
about: Request a new logo
|
||||||
title: ''
|
title: '[LOGO] '
|
||||||
labels: logo request
|
labels: logo request
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
@@ -9,10 +9,10 @@ assignees: ''
|
|||||||
|
|
||||||
# OS
|
# OS
|
||||||
```
|
```
|
||||||
paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
|
Paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
|
||||||
```
|
```
|
||||||
|
|
||||||
# Ascii
|
# Ascii
|
||||||
```
|
```
|
||||||
paste ascii art here. If you leave this empty, i will try to find the logo myself.
|
Paste ascii art here.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -215,8 +215,8 @@ jobs:
|
|||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||||
cmake --build . --target package --verbose
|
cmake --build . --target package --verbose
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
time ./fastfetch -c presets/ci.jsonc
|
time ./fastfetch
|
||||||
time ./fastfetch -c presets/ci.jsonc --format json
|
time ./fastfetch --format json
|
||||||
time ./flashfetch
|
time ./flashfetch
|
||||||
ldd fastfetch
|
ldd fastfetch
|
||||||
ctest
|
ctest
|
||||||
|
|||||||
@@ -7,3 +7,4 @@
|
|||||||
cscope.*
|
cscope.*
|
||||||
tags
|
tags
|
||||||
fastfetch.kdev4
|
fastfetch.kdev4
|
||||||
|
*.user
|
||||||
|
|||||||
@@ -1,3 +1,43 @@
|
|||||||
|
# 2.4.0
|
||||||
|
|
||||||
|
**We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.** One may use `-c /path/to/config.conf --gen-config` to migrate existing flag based config files.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* All flag based presets are removed
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Improve performance of detecting rpm and pkg package count (Packages, Linux / FreeBSD)
|
||||||
|
* Support Apple M3X temperature detection (CPU / GPU, macOS)
|
||||||
|
* `--ds-force-drm` support a new option `sysfs-only`
|
||||||
|
* Improve xfce4 version detection
|
||||||
|
* Detect WM and DE by enumerating running processes (WM / DE, FreeBSD)
|
||||||
|
* Add a new module `Physical Disk`, which detects product name, full size, serial number and so on.
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix crashes sometimes when `--logo-padding-top` is not set (Logo)
|
||||||
|
* Fix memory usage counting algorithm (Memory, macOS)
|
||||||
|
* Fix the behavior of `--no-buffer` in Windows
|
||||||
|
* Fix possible segfault in some devices (Display, Linux)
|
||||||
|
* Fix segfaults on first use of new images with Sixel flag (Image)
|
||||||
|
|
||||||
|
Logo:
|
||||||
|
* Remove unnecessary escaping for Adelie logo
|
||||||
|
* Add EshanizedOS
|
||||||
|
|
||||||
|
# 2.3.4
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix `--help` doesn't work when built without python
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Use `MemAvailable` if available (Memory, Linux)
|
||||||
|
* Improve performance of detecting dpkg package count (Packages, Linux)
|
||||||
|
|
||||||
|
# 2.3.3
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix `--help` doesn't work in Windows and some other platforms
|
||||||
|
|
||||||
# 2.3.2
|
# 2.3.2
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|||||||
+15
-6
@@ -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.3.2
|
VERSION 2.4.0
|
||||||
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"
|
||||||
@@ -206,7 +206,7 @@ endif()
|
|||||||
#############
|
#############
|
||||||
|
|
||||||
function(fastfetch_encode_c_string STR OUTVAR)
|
function(fastfetch_encode_c_string STR OUTVAR)
|
||||||
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
|
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
|
||||||
string(REPLACE "\\" "\\\\" TEMP "${TEMP}") # Escape backslashes
|
string(REPLACE "\\" "\\\\" TEMP "${TEMP}") # Escape backslashes
|
||||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
||||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
||||||
@@ -221,12 +221,15 @@ endfunction(fastfetch_load_text)
|
|||||||
|
|
||||||
find_package(Python)
|
find_package(Python)
|
||||||
if(Python_FOUND)
|
if(Python_FOUND)
|
||||||
# Minify JSON string. `io.open(0,encoding='utf-8')` is needed to avoid encoding issues on Windows
|
execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))"
|
||||||
execute_process(COMMAND ${Python_EXECUTABLE} -c "import io,json,sys;json.dump(json.load(io.open(0,encoding='utf-8')),sys.stdout,separators=(',', ':'),ensure_ascii=False)"
|
|
||||||
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
|
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
|
||||||
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
|
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
|
||||||
|
if(DATATEXT_JSON_HELP STREQUAL "")
|
||||||
|
message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
file(READ "src/data/help.json" TEMP)
|
message(STATUS "Python3 is not found, 'help.json' will not be minified")
|
||||||
|
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
|
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
|
||||||
@@ -337,6 +340,7 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/modules/opengl/opengl.c
|
src/modules/opengl/opengl.c
|
||||||
src/modules/os/os.c
|
src/modules/os/os.c
|
||||||
src/modules/packages/packages.c
|
src/modules/packages/packages.c
|
||||||
|
src/modules/physicaldisk/physicaldisk.c
|
||||||
src/modules/processes/processes.c
|
src/modules/processes/processes.c
|
||||||
src/modules/player/player.c
|
src/modules/player/player.c
|
||||||
src/modules/poweradapter/poweradapter.c
|
src/modules/poweradapter/poweradapter.c
|
||||||
@@ -391,6 +395,7 @@ if(LINUX)
|
|||||||
src/detection/cursor/cursor_linux.c
|
src/detection/cursor/cursor_linux.c
|
||||||
src/detection/bluetooth/bluetooth_linux.c
|
src/detection/bluetooth/bluetooth_linux.c
|
||||||
src/detection/disk/disk_linux.c
|
src/detection/disk/disk_linux.c
|
||||||
|
src/detection/physicaldisk/physicaldisk_linux.c
|
||||||
src/detection/diskio/diskio_linux.c
|
src/detection/diskio/diskio_linux.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
|
||||||
@@ -450,6 +455,7 @@ elseif(ANDROID)
|
|||||||
src/detection/cursor/cursor_nosupport.c
|
src/detection/cursor/cursor_nosupport.c
|
||||||
src/detection/cpuusage/cpuusage_linux.c
|
src/detection/cpuusage/cpuusage_linux.c
|
||||||
src/detection/disk/disk_linux.c
|
src/detection/disk/disk_linux.c
|
||||||
|
src/detection/physicaldisk/physicaldisk_linux.c
|
||||||
src/detection/diskio/diskio_linux.c
|
src/detection/diskio/diskio_linux.c
|
||||||
src/detection/displayserver/displayserver_android.c
|
src/detection/displayserver/displayserver_android.c
|
||||||
src/detection/font/font_nosupport.c
|
src/detection/font/font_nosupport.c
|
||||||
@@ -503,6 +509,7 @@ elseif(BSD)
|
|||||||
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/physicaldisk/physicaldisk_bsd.c
|
||||||
src/detection/diskio/diskio_bsd.c
|
src/detection/diskio/diskio_bsd.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
|
||||||
@@ -526,7 +533,7 @@ elseif(BSD)
|
|||||||
src/detection/netio/netio_bsd.c
|
src/detection/netio/netio_bsd.c
|
||||||
src/detection/opengl/opengl_linux.c
|
src/detection/opengl/opengl_linux.c
|
||||||
src/detection/os/os_linux.c
|
src/detection/os/os_linux.c
|
||||||
src/detection/packages/packages_linux.c
|
src/detection/packages/packages_bsd.c
|
||||||
src/detection/poweradapter/poweradapter_nosupport.c
|
src/detection/poweradapter/poweradapter_nosupport.c
|
||||||
src/detection/processes/processes_bsd.c
|
src/detection/processes/processes_bsd.c
|
||||||
src/detection/gtk_qt/qt.c
|
src/detection/gtk_qt/qt.c
|
||||||
@@ -563,6 +570,7 @@ elseif(APPLE)
|
|||||||
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/physicaldisk/physicaldisk_apple.c
|
||||||
src/detection/diskio/diskio_apple.c
|
src/detection/diskio/diskio_apple.c
|
||||||
src/detection/displayserver/displayserver_apple.c
|
src/detection/displayserver/displayserver_apple.c
|
||||||
src/detection/font/font_apple.m
|
src/detection/font/font_apple.m
|
||||||
@@ -616,6 +624,7 @@ elseif(WIN32)
|
|||||||
src/detection/cpuusage/cpuusage_windows.c
|
src/detection/cpuusage/cpuusage_windows.c
|
||||||
src/detection/cursor/cursor_windows.c
|
src/detection/cursor/cursor_windows.c
|
||||||
src/detection/disk/disk_windows.c
|
src/detection/disk/disk_windows.c
|
||||||
|
src/detection/physicaldisk/physicaldisk_windows.c
|
||||||
src/detection/diskio/diskio_windows.c
|
src/detection/diskio/diskio_windows.c
|
||||||
src/detection/displayserver/displayserver_windows.c
|
src/detection/displayserver/displayserver_windows.c
|
||||||
src/detection/font/font_windows.c
|
src/detection/font/font_windows.c
|
||||||
|
|||||||
@@ -89,3 +89,15 @@ Q: Why do you need a very performant version of neofetch?
|
|||||||
|
|
||||||
Q: It does not display [*] correctly for me, what can I do?
|
Q: It does not display [*] correctly for me, what can I do?
|
||||||
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||||
|
|
||||||
|
## Star History
|
||||||
|
|
||||||
|
Give it a star to support us!
|
||||||
|
|
||||||
|
<a href="https://star-history.com/#fastfetch-cli/fastfetch&Date">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date&theme=dark" />
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||||
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||||
|
</picture>
|
||||||
|
</a>
|
||||||
|
|||||||
+45
-2
@@ -251,8 +251,24 @@
|
|||||||
"description": "Set the path to the file containing OS information. Linux only"
|
"description": "Set the path to the file containing OS information. Linux only"
|
||||||
},
|
},
|
||||||
"dsForceDrm": {
|
"dsForceDrm": {
|
||||||
"type": "boolean",
|
"description": "Force display detection to use DRM. Linux only",
|
||||||
"description": "Force display detection to use `/sys/class/drm`. Linux only",
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "bool",
|
||||||
|
"const": false,
|
||||||
|
"description": "Try `wayland`, then `x11`, then `drm`"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Use `/sys/class/drm` only.",
|
||||||
|
"const": "sysfs-only"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bool",
|
||||||
|
"const": true,
|
||||||
|
"description": "Try `libdrm` first, then `sysfs` if libdrm failed"
|
||||||
|
}
|
||||||
|
],
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"wmiTimeout": {
|
"wmiTimeout": {
|
||||||
@@ -584,6 +600,7 @@
|
|||||||
"opengl",
|
"opengl",
|
||||||
"os",
|
"os",
|
||||||
"packages",
|
"packages",
|
||||||
|
"physicaldisk",
|
||||||
"player",
|
"player",
|
||||||
"poweradapter",
|
"poweradapter",
|
||||||
"processes",
|
"processes",
|
||||||
@@ -1353,6 +1370,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Physical Disk",
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"description": "Print physical disk information",
|
||||||
|
"const": "physicaldisk"
|
||||||
|
},
|
||||||
|
"namePrefix": {
|
||||||
|
"description": "Show disks with given name prefix only",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"$ref": "#/$defs/key"
|
||||||
|
},
|
||||||
|
"keyColor": {
|
||||||
|
"$ref": "#/$defs/keyColor"
|
||||||
|
},
|
||||||
|
"keyWidth": {
|
||||||
|
"$ref": "#/$defs/keyWidth"
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"$ref": "#/$defs/format"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Public IP",
|
"title": "Public IP",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:DiskIO:Version:Break:Colors
|
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
"weather",
|
"weather",
|
||||||
"netio",
|
"netio",
|
||||||
"diskio",
|
"diskio",
|
||||||
|
"physicaldisk",
|
||||||
"version",
|
"version",
|
||||||
"break",
|
"break",
|
||||||
"colors"
|
"colors"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
--logo arch
|
|
||||||
--os-format "Arch Linux ({12})"
|
|
||||||
--packages-format "{} (pacman)"
|
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
},
|
},
|
||||||
"netio",
|
"netio",
|
||||||
"diskio",
|
"diskio",
|
||||||
|
"physicaldisk",
|
||||||
"version",
|
"version",
|
||||||
"break",
|
"break",
|
||||||
"colors"
|
"colors"
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
# Load with --load-config examples/1
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Load with --load-config examples/2
|
|
||||||
# Note that you must replace the image path to an existing image to display it.
|
|
||||||
|
|
||||||
--kitty /home/linus/Bilder/Gentoo.png
|
|
||||||
--logo-width 28
|
|
||||||
|
|
||||||
--separator " "
|
|
||||||
|
|
||||||
--set-keyless HardwareStart=┌───────── \e[1mHardware Information\e[0m ─────────┐
|
|
||||||
--set-keyless SoftwareStart=├───────── \e[1mSoftware Information\e[0m ─────────┤
|
|
||||||
--set-keyless InformationEnd=└────────────────────────────────────────┘
|
|
||||||
--set-keyless Colors= \e[38m \e[37m \e[36m \e[35m \e[34m \e[33m \e[32m \e[31m
|
|
||||||
--structure HardwareStart:Host:CPU:GPU:SoftwareStart:OS:Kernel:WM:Shell:Terminal:TerminalFont:Packages:InformationEnd:Colors
|
|
||||||
|
|
||||||
--host-key " "
|
|
||||||
--cpu-key " "
|
|
||||||
--gpu-key " "
|
|
||||||
--os-key " "
|
|
||||||
--kernel-key " "
|
|
||||||
--wm-key " "
|
|
||||||
--shell-key " "
|
|
||||||
--terminal-key " "
|
|
||||||
--terminalfont-key " "
|
|
||||||
--packages-key " "
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# Load with --load-config example/3
|
|
||||||
|
|
||||||
--logo debian_small
|
|
||||||
--structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP
|
|
||||||
--binary-prefix si
|
|
||||||
--localip-show-loop false
|
|
||||||
--disk-folders /:/home:/boot:/efi
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# Load with --load-config examples/4
|
|
||||||
|
|
||||||
--color blue
|
|
||||||
--logo arch_small
|
|
||||||
--logo-padding-right 1
|
|
||||||
--separator " "
|
|
||||||
--structure DateTime:Break:Player:Media
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Load with --load-config examples/5
|
|
||||||
|
|
||||||
--logo none
|
|
||||||
--color reset_magenta
|
|
||||||
--structure Theme:Icons:Font:Cursor
|
|
||||||
--theme-key T
|
|
||||||
--theme-format {7}
|
|
||||||
--icons-key I
|
|
||||||
--icons-format {5}
|
|
||||||
--font-key F
|
|
||||||
--cursor-key C
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
--structure Host:Display:CPU:GPU:Memory:Disk:Battery
|
|
||||||
--memory-format "{?2}{2}{?}"
|
|
||||||
--disk-format "{?2}{2}{?}"
|
|
||||||
--battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
--structure "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Terminal:TerminalFont:CPU:GPU:Memory:Break:Colors"
|
|
||||||
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
|
||||||
--os-format "{3} {12}"
|
|
||||||
--display-key Resolution
|
|
||||||
--display-compact-type original
|
|
||||||
--de-format "{2} {3}"
|
|
||||||
--theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
|
||||||
--terminalfont-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
|
||||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}"
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Battery:Break:Packages:Shell:Display:Terminal:Break:CPU:GPU:Memory:Break:Colors
|
|
||||||
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
|
||||||
--battery-format "{/4}{-}{/}{4}%{?5} [{5}]{?}"
|
|
||||||
--display-key "Display"
|
|
||||||
--gpu-key "GPU"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
--structure OS:Kernel:Shell:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont
|
|
||||||
+4
-1
@@ -94,7 +94,10 @@ void ffStart(void)
|
|||||||
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
|
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
|
if (instance.config.display.noBuffer)
|
||||||
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
else
|
||||||
|
setvbuf(stdout, NULL, _IOFBF, 4096);
|
||||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||||
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
DWORD mode = 0;
|
DWORD mode = 0;
|
||||||
|
|||||||
+37
-6
@@ -10,6 +10,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
typedef int FFNativeFD;
|
typedef int FFNativeFD;
|
||||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||||
@@ -75,15 +76,45 @@ static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
|
|||||||
//Bit flags, combine with |
|
//Bit flags, combine with |
|
||||||
typedef enum FFPathType
|
typedef enum FFPathType
|
||||||
{
|
{
|
||||||
FF_PATHTYPE_REGULAR = 1,
|
FF_PATHTYPE_FILE = 1 << 0,
|
||||||
FF_PATHTYPE_LINK = 2,
|
FF_PATHTYPE_DIRECTORY = 1 << 1,
|
||||||
FF_PATHTYPE_DIRECTORY = 4
|
FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY,
|
||||||
} FFPathType;
|
} FFPathType;
|
||||||
|
|
||||||
#define FF_PATHTYPE_FILE (FF_PATHTYPE_REGULAR | FF_PATHTYPE_LINK)
|
static inline bool ffPathExists(const char* path, FFPathType pathType)
|
||||||
#define FF_PATHTYPE_ANY (FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY)
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
DWORD attr = GetFileAttributesA(path);
|
||||||
|
|
||||||
|
if(attr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(pathType & FF_PATHTYPE_FILE && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(pathType & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct stat fileStat;
|
||||||
|
if(stat(path, &fileStat) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||||
|
|
||||||
|
if(pathType & FF_PATHTYPE_FILE && mode == S_IFREG)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ffPathExists(const char* path, FFPathType pathType);
|
|
||||||
bool ffPathExpandEnv(const char* in, FFstrbuf* out);
|
bool ffPathExpandEnv(const char* in, FFstrbuf* out);
|
||||||
|
|
||||||
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
|
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
|
||||||
|
|||||||
+9
-24
@@ -3,10 +3,10 @@
|
|||||||
#include "util/unused.h"
|
#include "util/unused.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#if __has_include(<wordexp.h>)
|
#if __has_include(<wordexp.h>)
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
@@ -33,9 +33,14 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
|||||||
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
|
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||||
if(fd == -1)
|
if(fd == -1)
|
||||||
{
|
{
|
||||||
createSubfolders(fileName);
|
if (errno == ENOENT)
|
||||||
fd = open(fileName, openFlagsModes, openFlagsRights);
|
{
|
||||||
if(fd == -1)
|
createSubfolders(fileName);
|
||||||
|
fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||||
|
if(fd == -1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,26 +108,6 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
|||||||
return ffAppendFDBuffer(fd, buffer);
|
return ffAppendFDBuffer(fd, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ffPathExists(const char* path, FFPathType type)
|
|
||||||
{
|
|
||||||
struct stat fileStat;
|
|
||||||
if(stat(path, &fileStat) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
|
||||||
|
|
||||||
if(type & FF_PATHTYPE_REGULAR && mode == S_IFREG)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(type & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(type & FF_PATHTYPE_LINK && mode == S_IFLNK)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
|
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|||||||
+10
-23
@@ -18,11 +18,16 @@ static void createSubfolders(const char* fileName)
|
|||||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||||
{
|
{
|
||||||
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if(handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
createSubfolders(fileName);
|
if (GetLastError() == ERROR_PATH_NOT_FOUND)
|
||||||
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
{
|
||||||
if(handle == INVALID_HANDLE_VALUE)
|
createSubfolders(fileName);
|
||||||
|
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +42,7 @@ bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
|
|||||||
LARGE_INTEGER fileSize;
|
LARGE_INTEGER fileSize;
|
||||||
if(!GetFileSizeEx(handle, &fileSize))
|
if(!GetFileSizeEx(handle, &fileSize))
|
||||||
fileSize.QuadPart = 0;
|
fileSize.QuadPart = 0;
|
||||||
|
|
||||||
if (fileSize.QuadPart > 0)
|
if (fileSize.QuadPart > 0)
|
||||||
{
|
{
|
||||||
// optimize for files has a fixed length,
|
// optimize for files has a fixed length,
|
||||||
@@ -87,24 +92,6 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
|||||||
return ffAppendFDBuffer(handle, buffer);
|
return ffAppendFDBuffer(handle, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ffPathExists(const char* path, FFPathType type)
|
|
||||||
{
|
|
||||||
DWORD attr = GetFileAttributesA(path);
|
|
||||||
if(attr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(type & FF_PATHTYPE_REGULAR && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(type & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(type & FF_PATHTYPE_LINK && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
||||||
{
|
{
|
||||||
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
|
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ static FFModuleBaseInfo* O[] = {
|
|||||||
|
|
||||||
static FFModuleBaseInfo* P[] = {
|
static FFModuleBaseInfo* P[] = {
|
||||||
(void*) &instance.config.modules.packages,
|
(void*) &instance.config.modules.packages,
|
||||||
|
(void*) &instance.config.modules.physicalDisk,
|
||||||
(void*) &instance.config.modules.player,
|
(void*) &instance.config.modules.player,
|
||||||
(void*) &instance.config.modules.powerAdapter,
|
(void*) &instance.config.modules.powerAdapter,
|
||||||
(void*) &instance.config.modules.processes,
|
(void*) &instance.config.modules.processes,
|
||||||
|
|||||||
+21
-9
@@ -124,9 +124,14 @@
|
|||||||
"desc": "Set if only DRM should be used to detect displays",
|
"desc": "Set if only DRM should be used to detect displays",
|
||||||
"remark": "Use this option if you encountered problems with other detection method. Linux only",
|
"remark": "Use this option if you encountered problems with other detection method. Linux only",
|
||||||
"arg": {
|
"arg": {
|
||||||
"type": "bool",
|
"type": "enum",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"default": false
|
"default": "false",
|
||||||
|
"enum": {
|
||||||
|
"true": "Try `libdrm` first, then `sysfs` if libdrm failed",
|
||||||
|
"sysfs-only": "Use `/sys/class/drm` only",
|
||||||
|
"false": "Try `wayland`, then `x11`, then `drm`"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -548,7 +553,7 @@
|
|||||||
"desc": "Set the character to use in elapsed part of percentage bars",
|
"desc": "Set the character to use in elapsed part of percentage bars",
|
||||||
"arg": {
|
"arg": {
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"default": "■"
|
"default": "\u25a0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -942,6 +947,13 @@
|
|||||||
"type": "str"
|
"type": "str"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"long": "physicaldisk-name-prefix",
|
||||||
|
"desc": "Show disks with given name prefix only",
|
||||||
|
"arg": {
|
||||||
|
"type": "str"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"long": "bluetooth-show-disconnected",
|
"long": "bluetooth-show-disconnected",
|
||||||
"desc": "Set if disconnected bluetooth devices should be printed",
|
"desc": "Set if disconnected bluetooth devices should be printed",
|
||||||
@@ -1290,12 +1302,12 @@
|
|||||||
"arg": {
|
"arg": {
|
||||||
"type": "enum",
|
"type": "enum",
|
||||||
"enum": {
|
"enum": {
|
||||||
"block": "███",
|
"block": "\u2588\u2588\u2588",
|
||||||
"circle": "●",
|
"circle": "\u25cf",
|
||||||
"diamond": "◆",
|
"diamond": "\u25c6",
|
||||||
"triangle": "▲",
|
"triangle": "\u25b2",
|
||||||
"square": "■",
|
"square": "\u25a0",
|
||||||
"star": "★"
|
"star": "\u2605"
|
||||||
},
|
},
|
||||||
"default": "block"
|
"default": "block"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,16 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
|
|||||||
double result = 0;
|
double result = 0;
|
||||||
|
|
||||||
const char* error = NULL;
|
const char* error = NULL;
|
||||||
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
|
if (ffStrbufStartsWithS(cpuName, "Apple M"))
|
||||||
error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result);
|
{
|
||||||
else if(ffStrbufStartsWithS(cpuName, "Apple M2"))
|
switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10))
|
||||||
error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result);
|
{
|
||||||
|
case 1: error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result); break;
|
||||||
|
case 2: error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result); break;
|
||||||
|
case 3: error = ffDetectCoreTemps(FF_TEMP_CPU_M3X, &result); break;
|
||||||
|
default: error = "Unsupported Apple Silicon CPU";
|
||||||
|
}
|
||||||
|
}
|
||||||
else // PPC?
|
else // PPC?
|
||||||
error = ffDetectCoreTemps(FF_TEMP_CPU_X64, &result);
|
error = ffDetectCoreTemps(FF_TEMP_CPU_X64, &result);
|
||||||
|
|
||||||
|
|||||||
+13
-20
@@ -1,6 +1,7 @@
|
|||||||
#include "de.h"
|
#include "de.h"
|
||||||
|
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
|
#include "common/library.h"
|
||||||
#include "common/parsing.h"
|
#include "common/parsing.h"
|
||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "common/processing.h"
|
#include "common/processing.h"
|
||||||
@@ -87,26 +88,18 @@ static void getMate(FFstrbuf* result, FFDEOptions* options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* getXfce4ByLib(FFstrbuf* result)
|
||||||
|
{
|
||||||
|
const char* xfce_version_string(void); // from `xfce4/libxfce4util/xfce-misutils.h
|
||||||
|
FF_LIBRARY_LOAD(xfce4util, NULL, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xfce4util, xfce_version_string);
|
||||||
|
ffStrbufSetS(result, ffxfce_version_string());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
||||||
{
|
{
|
||||||
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", result);
|
getXfce4ByLib(result);
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
if(result->length == 0)
|
|
||||||
{
|
|
||||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
|
|
||||||
if (dirp)
|
|
||||||
{
|
|
||||||
struct dirent* entry;
|
|
||||||
while((entry = readdir(dirp)) != NULL)
|
|
||||||
{
|
|
||||||
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
|
|
||||||
continue;
|
|
||||||
ffStrbufAppendS(result, &entry->d_name[5]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(result->length == 0 && options->slowVersionDetection)
|
if(result->length == 0 && options->slowVersionDetection)
|
||||||
{
|
{
|
||||||
@@ -117,8 +110,8 @@ static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
|||||||
NULL
|
NULL
|
||||||
});
|
});
|
||||||
|
|
||||||
ffStrbufSubstrBeforeFirstC(result, '(');
|
ffStrbufSubstrBeforeFirstC(result, ')');
|
||||||
ffStrbufSubstrAfterFirstC(result, ' ');
|
ffStrbufSubstrAfterLastC(result, ' ');
|
||||||
ffStrbufTrim(result, ' ');
|
ffStrbufTrim(result, ' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,14 +106,6 @@ static void detectName(FFDisk* disk)
|
|||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
|
||||||
|
|
||||||
//Detect USB devices. Code is put here to reuse deviceStat
|
|
||||||
//https://stackoverflow.com/a/73302717
|
|
||||||
ffStrbufAppendS(&basePath, "/dev/disk/by-id/");
|
|
||||||
detectNameFromPath(disk, &deviceStat, &basePath);
|
|
||||||
if (ffStrbufStartsWithS(&disk->name, "usb-"))
|
|
||||||
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
|
||||||
ffStrbufClear(&disk->name);
|
|
||||||
|
|
||||||
//Try label first
|
//Try label first
|
||||||
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
|
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
|
||||||
detectNameFromPath(disk, &deviceStat, &basePath);
|
detectNameFromPath(disk, &deviceStat, &basePath);
|
||||||
@@ -197,9 +189,6 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
|
|||||||
|
|
||||||
static bool isRemovable(FFDisk* currentDisk)
|
static bool isRemovable(FFDisk* currentDisk)
|
||||||
{
|
{
|
||||||
// https://stackoverflow.com/a/73302025
|
|
||||||
// Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
|
|
||||||
// USB devices should be handled in detectName
|
|
||||||
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreateS("/sys/block/");
|
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreateS("/sys/block/");
|
||||||
|
|
||||||
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath.chars);
|
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath.chars);
|
||||||
@@ -218,11 +207,10 @@ static bool isRemovable(FFDisk* currentDisk)
|
|||||||
|
|
||||||
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
|
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
|
||||||
|
|
||||||
// /sys/block/sdx/removable
|
// /sys/block/sdx/device/delete
|
||||||
ffStrbufAppendS(&basePath, entry->d_name);
|
ffStrbufAppendS(&basePath, entry->d_name);
|
||||||
ffStrbufAppendS(&basePath, "/removable");
|
ffStrbufAppendS(&basePath, "/device/delete");
|
||||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
return ffPathExists(basePath.chars, FF_PATHTYPE_FILE);
|
||||||
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -230,14 +218,12 @@ static bool isRemovable(FFDisk* currentDisk)
|
|||||||
|
|
||||||
static void detectType(const FFlist* disks, FFDisk* currentDisk)
|
static void detectType(const FFlist* disks, FFDisk* currentDisk)
|
||||||
{
|
{
|
||||||
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
|
if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/boot") || ffStrbufStartsWithS(¤tDisk->mountpoint, "/efi"))
|
||||||
|
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||||
if(isRemovable(currentDisk))
|
else if(isRemovable(currentDisk))
|
||||||
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||||
else if(isSubvolume(disks, currentDisk))
|
else if(isSubvolume(disks, currentDisk))
|
||||||
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
||||||
else if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/boot") || ffStrbufStartsWithS(¤tDisk->mountpoint, "/efi"))
|
|
||||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
|
||||||
else
|
else
|
||||||
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
|
|||||||
{
|
{
|
||||||
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
|
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
|
||||||
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
|
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
|
||||||
if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
|
if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath))
|
||||||
return "Network interface name changed";
|
return "Physical disk device path changed";
|
||||||
|
|
||||||
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
|
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
|
||||||
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
|
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
|
||||||
|
|||||||
@@ -2,19 +2,9 @@
|
|||||||
|
|
||||||
#include "fastfetch.h"
|
#include "fastfetch.h"
|
||||||
|
|
||||||
typedef enum FFDiskIOPhysicalType
|
|
||||||
{
|
|
||||||
FF_DISKIO_PHYSICAL_TYPE_UNKNOWN,
|
|
||||||
FF_DISKIO_PHYSICAL_TYPE_HDD,
|
|
||||||
FF_DISKIO_PHYSICAL_TYPE_SSD,
|
|
||||||
} FFDiskIOPhysicalType;
|
|
||||||
|
|
||||||
typedef struct FFDiskIOResult
|
typedef struct FFDiskIOResult
|
||||||
{
|
{
|
||||||
FFstrbuf name;
|
FFstrbuf name;
|
||||||
FFstrbuf interconnect;
|
|
||||||
FFDiskIOPhysicalType type;
|
|
||||||
uint64_t size;
|
|
||||||
FFstrbuf devPath;
|
FFstrbuf devPath;
|
||||||
uint64_t bytesRead;
|
uint64_t bytesRead;
|
||||||
uint64_t readCount;
|
uint64_t readCount;
|
||||||
|
|||||||
@@ -48,8 +48,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||||
ffStrbufInitS(&device->name, deviceName);
|
ffStrbufInitS(&device->name, deviceName);
|
||||||
ffStrbufInit(&device->devPath);
|
ffStrbufInit(&device->devPath);
|
||||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
|
||||||
device->size = 0;
|
|
||||||
|
|
||||||
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
|
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
|
||||||
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
|
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
|
||||||
@@ -62,34 +60,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
ffCfStrGetString(bsdName, &device->devPath);
|
ffCfStrGetString(bsdName, &device->devPath);
|
||||||
ffStrbufPrependS(&device->devPath, "/dev/");
|
ffStrbufPrependS(&device->devPath, "/dev/");
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
|
|
||||||
if (mediaSize)
|
|
||||||
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
|
|
||||||
else
|
|
||||||
device->size = 0;
|
|
||||||
|
|
||||||
ffStrbufInit(&device->interconnect);
|
|
||||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
|
|
||||||
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
|
|
||||||
{
|
|
||||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
|
||||||
if (protocolCharacteristics)
|
|
||||||
ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->interconnect);
|
|
||||||
|
|
||||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
|
||||||
if (deviceCharacteristics)
|
|
||||||
{
|
|
||||||
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
|
|
||||||
if (mediumType)
|
|
||||||
{
|
|
||||||
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
|
|
||||||
device->type = FF_DISKIO_PHYSICAL_TYPE_SSD;
|
|
||||||
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
|
|
||||||
device->type = FF_DISKIO_PHYSICAL_TYPE_HDD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -32,35 +32,25 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
|||||||
if (provider->lg_geom->lg_rank != 1)
|
if (provider->lg_geom->lg_rank != 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
|
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||||
FFDiskIOPhysicalType type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
|
||||||
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
|
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
|
||||||
{
|
{
|
||||||
if (ffStrEquals(ptr->lg_name, "descr"))
|
if (ffStrEquals(ptr->lg_name, "descr"))
|
||||||
ffStrbufSetS(&name, ptr->lg_val);
|
ffStrbufSetS(&name, ptr->lg_val);
|
||||||
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
|
|
||||||
type = ffStrEquals(ptr->lg_val, "0") ? FF_DISKIO_PHYSICAL_TYPE_SSD : FF_DISKIO_PHYSICAL_TYPE_HDD;
|
|
||||||
}
|
}
|
||||||
|
if (name.length == 0)
|
||||||
|
ffStrbufSetS(&name, provider->lg_name);
|
||||||
|
|
||||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||||
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
|
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
|
||||||
ffStrbufInit(&device->interconnect);
|
|
||||||
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
|
|
||||||
{
|
|
||||||
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
|
|
||||||
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
|
|
||||||
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
|
|
||||||
}
|
|
||||||
device->bytesRead = snapIter->bytes[DEVSTAT_READ];
|
device->bytesRead = snapIter->bytes[DEVSTAT_READ];
|
||||||
device->readCount = snapIter->operations[DEVSTAT_READ];
|
device->readCount = snapIter->operations[DEVSTAT_READ];
|
||||||
device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE];
|
device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE];
|
||||||
device->writeCount = snapIter->operations[DEVSTAT_WRITE];
|
device->writeCount = snapIter->operations[DEVSTAT_WRITE];
|
||||||
device->size = (uint64_t) provider->lg_mediasize;
|
|
||||||
ffStrbufInitMove(&device->name, &name);
|
ffStrbufInitMove(&device->name, &name);
|
||||||
device->type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
geom_stats_snapshot_free(snap);
|
geom_stats_snapshot_free(snap);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
|
#include "common/properties.h"
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -7,107 +8,75 @@
|
|||||||
|
|
||||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||||
{
|
{
|
||||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS("/dev/disk/by-id/");
|
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
|
||||||
uint32_t baseDirLength = baseDir.length;
|
if(sysBlockDirp == NULL)
|
||||||
|
return "opendir(\"/sys/block/\") == NULL";
|
||||||
|
|
||||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
|
struct dirent* sysBlockEntry;
|
||||||
if(dirp == NULL)
|
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
|
||||||
return "opendir(batteryDir) == NULL";
|
|
||||||
|
|
||||||
struct dirent* entry;
|
|
||||||
while ((entry = readdir(dirp)) != NULL)
|
|
||||||
{
|
{
|
||||||
if (entry->d_name[0] == '.')
|
const char* const devName = sysBlockEntry->d_name;
|
||||||
|
|
||||||
|
if (devName[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char* part = strstr(entry->d_name, "-part");
|
|
||||||
if (part && isdigit(part[strlen("-part")]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive identifier
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Other exceptions?
|
|
||||||
|
|
||||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
|
||||||
char pathDev[PATH_MAX];
|
|
||||||
ssize_t pathLen = readlink(baseDir.chars, pathDev, PATH_MAX);
|
|
||||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
|
||||||
|
|
||||||
if (pathLen < 0) continue;
|
|
||||||
pathDev[pathLen] = '\0'; // ../../nvme0n1
|
|
||||||
|
|
||||||
char pathDev1[PATH_MAX];
|
|
||||||
const char* devName = basename(pathDev);
|
|
||||||
snprintf(pathDev1, PATH_MAX, "/dev/%s", devName);
|
|
||||||
|
|
||||||
// Avoid duplicated disks
|
|
||||||
bool flag = false;
|
|
||||||
FF_LIST_FOR_EACH(FFDiskIOResult, disk, *result)
|
|
||||||
{
|
|
||||||
if (ffStrbufEqualS(&disk->devPath, pathDev1))
|
|
||||||
{
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flag) continue;
|
|
||||||
|
|
||||||
char pathSysBlock[PATH_MAX];
|
char pathSysBlock[PATH_MAX];
|
||||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r");
|
char pathSysDeviceReal[PATH_MAX];
|
||||||
if (!sysBlockStat) continue;
|
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
|
||||||
|
if (pathLength < 0)
|
||||||
|
continue;
|
||||||
|
pathSysDeviceReal[pathLength] = '\0';
|
||||||
|
|
||||||
// I/Os merges sectors ticks ...
|
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
|
||||||
uint64_t nRead, sectorRead, nWritten, sectorWritten;
|
continue;
|
||||||
if (fscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, §orRead, &nWritten, §orWritten) == 0)
|
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
|
||||||
|
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||||
char* slash = strchr(entry->d_name, '-');
|
ffStrbufInit(&device->name);
|
||||||
if (slash)
|
|
||||||
{
|
|
||||||
char* slash2 = strchr(slash + 1, '-');
|
|
||||||
if (slash2)
|
|
||||||
ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1);
|
|
||||||
else
|
|
||||||
ffStrbufInitS(&device->name, slash + 1);
|
|
||||||
ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ffStrbufInitS(&device->name, entry->d_name);
|
|
||||||
ffStrbufInit(&device->interconnect);
|
|
||||||
}
|
|
||||||
ffStrbufReplaceAllC(&device->name, '_', ' ');
|
|
||||||
|
|
||||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
|
||||||
{
|
{
|
||||||
ffStrbufDestroy(&device->name);
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||||
ffStrbufDestroy(&device->interconnect);
|
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||||
result->length--;
|
if (device->name.length > 0)
|
||||||
continue;
|
ffStrbufAppendC(&device->name, ' ');
|
||||||
|
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||||
|
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||||
|
ffStrbufTrim(&device->name, ' ');
|
||||||
|
|
||||||
|
if (device->name.length == 0)
|
||||||
|
ffStrbufSetS(&device->name, devName);
|
||||||
|
|
||||||
|
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||||
|
{
|
||||||
|
ffStrbufDestroy(&device->name);
|
||||||
|
result->length--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufInitS(&device->devPath, pathDev1);
|
// I/Os merges sectors ticks ...
|
||||||
|
uint64_t nRead, sectorRead, nWritten, sectorWritten;
|
||||||
|
{
|
||||||
|
char sysBlockStat[PROC_FILE_BUFFSIZ];
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
|
||||||
|
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(sysBlockStat) - 1, sysBlockStat);
|
||||||
|
if (fileSize <= 0) continue;
|
||||||
|
sysBlockStat[fileSize] = '\0';
|
||||||
|
if (sscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||||
device->bytesRead = sectorRead * 512;
|
device->bytesRead = sectorRead * 512;
|
||||||
device->bytesWritten = sectorWritten * 512;
|
device->bytesWritten = sectorWritten * 512;
|
||||||
device->readCount = nRead;
|
device->readCount = nRead;
|
||||||
device->writeCount = nWritten;
|
device->writeCount = nWritten;
|
||||||
|
|
||||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
|
|
||||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
|
||||||
if (ffReadFileBuffer(pathSysBlock, &buffer))
|
|
||||||
device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
|
|
||||||
else
|
|
||||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
|
||||||
|
|
||||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
|
|
||||||
if (ffReadFileBuffer(pathSysBlock, &buffer))
|
|
||||||
device->size = ffStrbufToUInt(&buffer, 0);
|
|
||||||
else
|
|
||||||
device->size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -1,101 +1,82 @@
|
|||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
#include "util/windows/registry.h"
|
|
||||||
#include "util/windows/unicode.h"
|
#include "util/windows/unicode.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||||
{
|
{
|
||||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
|
||||||
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", &hKey, NULL))
|
|
||||||
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum\") failed";
|
|
||||||
|
|
||||||
uint32_t nDevices;
|
|
||||||
if (!ffRegReadUint(hKey, L"Count", &nDevices, NULL))
|
|
||||||
return "ffRegReadUint(hKey, L\"Count\", &nDevices) failed";
|
|
||||||
|
|
||||||
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
|
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
|
||||||
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
|
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
|
||||||
for (uint32_t idev = 0; idev <= nDevices; ++idev) {
|
for (uint32_t idev = 0; ; ++idev)
|
||||||
|
{
|
||||||
_ultow(idev, pNum, 10);
|
_ultow(idev, pNum, 10);
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
if (hDevice == INVALID_HANDLE_VALUE)
|
if (hDevice == INVALID_HANDLE_VALUE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DWORD retSize;
|
||||||
|
char sddBuffer[4096];
|
||||||
|
if(!DeviceIoControl(
|
||||||
|
hDevice,
|
||||||
|
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||||
|
&(STORAGE_PROPERTY_QUERY) {
|
||||||
|
.PropertyId = StorageDeviceProperty,
|
||||||
|
.QueryType = PropertyStandardQuery,
|
||||||
|
},
|
||||||
|
sizeof(STORAGE_PROPERTY_QUERY),
|
||||||
|
&sddBuffer,
|
||||||
|
sizeof(sddBuffer),
|
||||||
|
&retSize,
|
||||||
|
NULL
|
||||||
|
) || retSize == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DISK_PERFORMANCE diskPerformance;
|
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||||
DWORD ioctrlSize = sizeof(diskPerformance);
|
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||||
DWORD dwSize;
|
|
||||||
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
|
ffStrbufInit(&device->name);
|
||||||
|
if (sdd->VendorIdOffset != 0)
|
||||||
{
|
{
|
||||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
|
||||||
ffStrbufInit(&device->name);
|
ffStrbufTrim(&device->name, ' ');
|
||||||
ffStrbufInit(&device->interconnect);
|
}
|
||||||
if (ffRegReadStrbuf(hKey, pNum, &device->name, NULL))
|
if (sdd->ProductIdOffset != 0)
|
||||||
{
|
{
|
||||||
// SCSI\Disk&Ven_NVMe&Prod_WDC_PC_SN810_SDC\5&19cebb7&0&000000
|
if (device->name.length)
|
||||||
uint32_t index = ffStrbufFirstIndexC(&device->name, '\\');
|
ffStrbufAppendC(&device->name, ' ');
|
||||||
if (index != device->name.length)
|
|
||||||
{
|
|
||||||
ffStrbufAppendNS(&device->interconnect, index, device->name.chars); // SCSI
|
|
||||||
ffStrbufSubstrAfter(&device->name, index);
|
|
||||||
}
|
|
||||||
ffStrbufSubstrBeforeLastC(&device->name, '\\');
|
|
||||||
ffStrbufSubstrAfterFirstS(&device->name, "&Ven_");
|
|
||||||
ffStrbufRemoveS(&device->name, "&Prod");
|
|
||||||
ffStrbufReplaceAllC(&device->name, '_', ' ');
|
|
||||||
ffStrbufTrim(&device->name, ' ');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ffStrbufSetWS(&device->name, szDevice);
|
|
||||||
|
|
||||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||||
{
|
ffStrbufTrimRight(&device->name, ' ');
|
||||||
ffStrbufDestroy(&device->name);
|
}
|
||||||
ffStrbufDestroy(&device->interconnect);
|
|
||||||
result->length--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ffStrbufInitWS(&device->devPath, szDevice);
|
if (!device->name.length)
|
||||||
device->bytesRead = (uint64_t) diskPerformance.BytesRead.QuadPart;
|
ffStrbufAppendF(&device->name, "PhysicalDrive%u", (unsigned) idev);
|
||||||
device->readCount = (uint64_t) diskPerformance.ReadCount;
|
|
||||||
device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart;
|
|
||||||
device->writeCount = (uint64_t) diskPerformance.WriteCount;
|
|
||||||
|
|
||||||
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
|
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||||
DWORD retSize = 0;
|
{
|
||||||
if(DeviceIoControl(
|
ffStrbufDestroy(&device->name);
|
||||||
hDevice,
|
result->length--;
|
||||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
continue;
|
||||||
&(STORAGE_PROPERTY_QUERY) {
|
}
|
||||||
.PropertyId = StorageDeviceSeekPenaltyProperty,
|
|
||||||
.QueryType = PropertyStandardQuery,
|
|
||||||
},
|
|
||||||
sizeof(STORAGE_PROPERTY_QUERY),
|
|
||||||
&dspd,
|
|
||||||
sizeof(dspd),
|
|
||||||
&retSize,
|
|
||||||
NULL
|
|
||||||
) && retSize == sizeof(dspd))
|
|
||||||
device->type = dspd.IncursSeekPenalty ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
|
|
||||||
else
|
|
||||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
|
||||||
|
|
||||||
DISK_GEOMETRY_EX dge = {};
|
ffStrbufInitWS(&device->devPath, szDevice);
|
||||||
if(DeviceIoControl(
|
|
||||||
hDevice,
|
DISK_PERFORMANCE dp = {};
|
||||||
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
|
||||||
NULL,
|
{
|
||||||
0,
|
device->bytesRead = (uint64_t) dp.BytesRead.QuadPart;
|
||||||
&dge,
|
device->readCount = (uint64_t) dp.ReadCount;
|
||||||
sizeof(dge),
|
device->bytesWritten = (uint64_t) dp.BytesWritten.QuadPart;
|
||||||
&retSize,
|
device->writeCount = (uint64_t) dp.WriteCount;
|
||||||
NULL))
|
}
|
||||||
device->size = (uint64_t) dge.DiskSize.QuadPart;
|
else
|
||||||
else
|
{
|
||||||
device->size = 0;
|
ffStrbufDestroy(&device->name);
|
||||||
|
result->length--;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#define FF_DE_PRETTY_LXDE "LXDE"
|
#define FF_DE_PRETTY_LXDE "LXDE"
|
||||||
#define FF_DE_PRETTY_LXQT "LXQT"
|
#define FF_DE_PRETTY_LXQT "LXQT"
|
||||||
#define FF_DE_PRETTY_BUDGIE "Budgie"
|
#define FF_DE_PRETTY_BUDGIE "Budgie"
|
||||||
|
#define FF_DE_PRETTY_CDE "CDE"
|
||||||
#define FF_DE_PRETTY_UNITY "Unity"
|
#define FF_DE_PRETTY_UNITY "Unity"
|
||||||
|
|
||||||
#define FF_WM_PRETTY_KWIN "KWin"
|
#define FF_WM_PRETTY_KWIN "KWin"
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
#define FF_WM_PRETTY_HERBSTLUFTWM "herbstluftwm"
|
#define FF_WM_PRETTY_HERBSTLUFTWM "herbstluftwm"
|
||||||
#define FF_WM_PRETTY_ICEWM "IceWM"
|
#define FF_WM_PRETTY_ICEWM "IceWM"
|
||||||
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
|
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
|
||||||
|
#define FF_WM_PRETTY_DTWM "dtwm"
|
||||||
|
|
||||||
|
|
||||||
#define FF_WM_PROTOCOL_TTY "TTY"
|
#define FF_WM_PROTOCOL_TTY "TTY"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
|||||||
ffStrbufInit(&ds->dePrettyName);
|
ffStrbufInit(&ds->dePrettyName);
|
||||||
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
||||||
|
|
||||||
if (!instance.config.general.dsForceDrm)
|
if (instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE)
|
||||||
{
|
{
|
||||||
//We try wayland as our preferred display server, as it supports the most features.
|
//We try wayland as our preferred display server, as it supports the most features.
|
||||||
//This method can't detect the name of our WM / DE
|
//This method can't detect the name of our WM / DE
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
|||||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||||
uint32_t drmDirWithDnameLength = drmDir.length;
|
uint32_t drmDirWithDnameLength = drmDir.length;
|
||||||
|
|
||||||
ffStrbufAppendS(&drmDir, "/enabled");
|
ffStrbufAppendS(&drmDir, "/status");
|
||||||
char enabled = 'd'; // disabled
|
char status = 'd'; // disconnected
|
||||||
ffReadFileData(drmDir.chars, sizeof(enabled), &enabled);
|
ffReadFileData(drmDir.chars, sizeof(status), &status);
|
||||||
if (enabled != 'e') // enabled
|
if (status != 'c') // connected
|
||||||
{
|
{
|
||||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||||
continue;
|
continue;
|
||||||
@@ -152,6 +152,49 @@ static inline const char* drmType2Name(uint32_t connector_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
|
||||||
|
{
|
||||||
|
const char* drmDirPath = "/sys/class/drm/";
|
||||||
|
|
||||||
|
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
|
||||||
|
if(dirp == NULL)
|
||||||
|
return "opendir(drmDirPath) failed";
|
||||||
|
|
||||||
|
FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
|
||||||
|
ffStrbufAppendS(&drmDir, drmDirPath);
|
||||||
|
|
||||||
|
uint32_t drmDirLength = drmDir.length;
|
||||||
|
|
||||||
|
struct dirent* entry;
|
||||||
|
while((entry = readdir(dirp)) != NULL)
|
||||||
|
{
|
||||||
|
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||||
|
uint32_t drmDirWithDnameLength = drmDir.length;
|
||||||
|
|
||||||
|
ffStrbufAppendS(&drmDir, "/connector_id");
|
||||||
|
ffReadFileBuffer(drmDir.chars, name);
|
||||||
|
if (ffStrbufToUInt(name, 0) != connId)
|
||||||
|
{
|
||||||
|
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
|
||||||
|
ffStrbufClear(name);
|
||||||
|
ffStrbufAppendS(&drmDir, "/edid");
|
||||||
|
uint8_t edidData[128];
|
||||||
|
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
|
||||||
|
ffEdidGetName(edidData, name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufClear(name);
|
||||||
|
return "Failed to match connector ID";
|
||||||
|
}
|
||||||
|
|
||||||
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
|
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
|
||||||
@@ -162,6 +205,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
|||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeResources)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
|
||||||
@@ -196,18 +240,56 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
|||||||
if (!conn)
|
if (!conn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (conn->connection != DRM_MODE_CONNECTED)
|
if (conn->connection == DRM_MODE_CONNECTED)
|
||||||
goto next_conn;
|
|
||||||
|
|
||||||
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
|
|
||||||
if (!encoder)
|
|
||||||
goto next_conn;
|
|
||||||
|
|
||||||
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
|
|
||||||
if (!crtc)
|
|
||||||
goto next_encoder;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
|
||||||
|
uint32_t width = 0, height = 0, refreshRate = 0;
|
||||||
|
|
||||||
|
if (encoder)
|
||||||
|
{
|
||||||
|
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
|
||||||
|
if (crtc)
|
||||||
|
{
|
||||||
|
width = crtc->mode.vdisplay;
|
||||||
|
height = crtc->mode.hdisplay;
|
||||||
|
refreshRate = crtc->mode.vrefresh;
|
||||||
|
if (refreshRate == 0)
|
||||||
|
{
|
||||||
|
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
|
||||||
|
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
||||||
|
{
|
||||||
|
drmModeModeInfo* mode = &conn->modes[iMode];
|
||||||
|
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
|
||||||
|
{
|
||||||
|
refreshRate = mode->vrefresh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffdrmModeFreeCrtc(crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
ffdrmModeFreeEncoder(encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
{
|
||||||
|
// NVIDIA DRM driver seems incomplete and conn->encoder_id == 0
|
||||||
|
// Assume preferred resolution is used as what we do in drmParseSys
|
||||||
|
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
||||||
|
{
|
||||||
|
drmModeModeInfo* mode = &conn->modes[iMode];
|
||||||
|
|
||||||
|
if (mode->type & DRM_MODE_TYPE_PREFERRED)
|
||||||
|
{
|
||||||
|
width = mode->hdisplay;
|
||||||
|
height = mode->vdisplay;
|
||||||
|
refreshRate = mode->vrefresh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||||
|
|
||||||
for (int iProp = 0; iProp < conn->count_props; ++iProp)
|
for (int iProp = 0; iProp < conn->count_props; ++iProp)
|
||||||
@@ -219,60 +301,58 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
|||||||
uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE);
|
uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE);
|
||||||
if (type == DRM_MODE_PROP_BLOB && ffStrEquals(prop->name, "EDID"))
|
if (type == DRM_MODE_PROP_BLOB && ffStrEquals(prop->name, "EDID"))
|
||||||
{
|
{
|
||||||
// Stangely, prop->count_blobs is 0 and prop->blob_ids is NULL
|
drmModePropertyBlobPtr blob = NULL;
|
||||||
drmModePropertyBlobPtr blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
|
|
||||||
if (blob->length >= 128)
|
if (prop->count_blobs > 0 && prop->blob_ids != NULL)
|
||||||
ffEdidGetName(blob->data, &name);
|
blob = ffdrmModeGetPropertyBlob(fd, prop->blob_ids[0]);
|
||||||
ffdrmModeFreePropertyBlob(blob);
|
else
|
||||||
|
blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
|
||||||
|
|
||||||
|
if (blob)
|
||||||
|
{
|
||||||
|
if (blob->length >= 128)
|
||||||
|
ffEdidGetName(blob->data, &name);
|
||||||
|
ffdrmModeFreePropertyBlob(blob);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ffdrmModeFreeProperty(prop);
|
ffdrmModeFreeProperty(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name.length == 0)
|
||||||
|
{
|
||||||
|
drmGetNameByConnId(conn->connector_id, &name);
|
||||||
|
}
|
||||||
|
|
||||||
if (name.length == 0)
|
if (name.length == 0)
|
||||||
{
|
{
|
||||||
const char* connectorTypeName = drmType2Name(conn->connector_type);
|
const char* connectorTypeName = drmType2Name(conn->connector_type);
|
||||||
if (connectorTypeName == NULL)
|
if (connectorTypeName == NULL)
|
||||||
connectorTypeName = "Unknown";
|
connectorTypeName = "Unknown";
|
||||||
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn);
|
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t refreshRate = crtc->mode.vrefresh;
|
ffdsAppendDisplay(result,
|
||||||
if (refreshRate == 0)
|
width,
|
||||||
{
|
height,
|
||||||
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
|
|
||||||
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
|
||||||
{
|
|
||||||
drmModeModeInfo* mode = &conn->modes[iMode];
|
|
||||||
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
|
|
||||||
{
|
|
||||||
refreshRate = mode->vrefresh;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ffdsAppendDisplay(
|
|
||||||
result,
|
|
||||||
crtc->width, crtc->height,
|
|
||||||
refreshRate,
|
refreshRate,
|
||||||
0, 0,
|
0,
|
||||||
|
0,
|
||||||
0,
|
0,
|
||||||
&name,
|
&name,
|
||||||
FF_DISPLAY_TYPE_UNKNOWN,
|
conn->connector_type == DRM_MODE_CONNECTOR_eDP
|
||||||
|
? FF_DISPLAY_TYPE_BUILTIN
|
||||||
|
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB
|
||||||
|
? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN,
|
||||||
false,
|
false,
|
||||||
0
|
conn->connector_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffdrmModeFreeCrtc(crtc);
|
|
||||||
|
|
||||||
next_encoder:
|
|
||||||
ffdrmModeFreeEncoder(encoder);
|
|
||||||
|
|
||||||
next_conn:
|
|
||||||
ffdrmModeFreeConnector(conn);
|
ffdrmModeFreeConnector(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffdrmModeFreeResources(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffdrmFreeDevices(devices, nDevices);
|
ffdrmFreeDevices(devices, nDevices);
|
||||||
@@ -285,8 +365,11 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
|||||||
void ffdsConnectDrm(FFDisplayServerResult* result)
|
void ffdsConnectDrm(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
#ifdef FF_HAVE_DRM
|
#ifdef FF_HAVE_DRM
|
||||||
if (drmConnectLibdrm(result) == NULL)
|
if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
|
||||||
return;
|
{
|
||||||
|
if (drmConnectLibdrm(result) == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
drmParseSysfs(result);
|
drmParseSysfs(result);
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
#include "displayserver_linux.h"
|
#include "displayserver_linux.h"
|
||||||
#include "common/io/io.h"
|
|
||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "common/processing.h"
|
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
#include "util/mallocHelper.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#else
|
||||||
|
#include "common/io/io.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* parseEnv(void)
|
static const char* parseEnv(void)
|
||||||
{
|
{
|
||||||
@@ -46,10 +52,12 @@ static const char* parseEnv(void)
|
|||||||
if(getenv("TDE_FULL_SESSION") != NULL)
|
if(getenv("TDE_FULL_SESSION") != NULL)
|
||||||
return "Trinity";
|
return "Trinity";
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
if(
|
if(
|
||||||
getenv("WAYLAND_DISPLAY") != NULL &&
|
getenv("WAYLAND_DISPLAY") != NULL &&
|
||||||
ffPathExists("/mnt/wslg/", FF_PATHTYPE_DIRECTORY)
|
ffPathExists("/mnt/wslg/", FF_PATHTYPE_DIRECTORY)
|
||||||
) return "WSLg";
|
) return "WSLg";
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -60,52 +68,54 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(
|
if(
|
||||||
strcasecmp(name, "kwin_wayland") == 0 ||
|
ffStrEqualsIgnCase(name, "kwin_wayland") ||
|
||||||
strcasecmp(name, "kwin_wayland_wrapper") == 0 ||
|
ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
|
||||||
strcasecmp(name, "kwin_x11") == 0 ||
|
ffStrEqualsIgnCase(name, "kwin_x11") ||
|
||||||
strcasecmp(name, "kwin_x11_wrapper") == 0 ||
|
ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
|
||||||
strcasecmp(name, "kwin") == 0
|
ffStrEqualsIgnCase(name, "kwin")
|
||||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
|
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "gnome-shell") == 0 ||
|
ffStrEqualsIgnCase(name, "gnome-shell") ||
|
||||||
strcasecmp(name, "gnome shell") == 0 ||
|
ffStrEqualsIgnCase(name, "gnome shell") ||
|
||||||
strcasecmp(name, "gnome-session-binary") == 0 ||
|
ffStrEqualsIgnCase(name, "gnome-session-binary") ||
|
||||||
strcasecmp(name, "Mutter") == 0
|
ffStrEqualsIgnCase(name, "Mutter")
|
||||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
|
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "cinnamon-session") == 0 ||
|
ffStrEqualsIgnCase(name, "cinnamon-session") ||
|
||||||
strcasecmp(name, "Muffin") == 0 ||
|
ffStrEqualsIgnCase(name, "Muffin") ||
|
||||||
strcasecmp(name, "Mutter (Muffin)") == 0
|
ffStrEqualsIgnCase(name, "Mutter (Muffin)")
|
||||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
|
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
|
||||||
else if(strcasecmp(name, "sway") == 0)
|
else if(ffStrEqualsIgnCase(name, "sway"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_SWAY);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_SWAY);
|
||||||
else if(strcasecmp(name, "weston") == 0)
|
else if(ffStrEqualsIgnCase(name, "weston"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WESTON);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WESTON);
|
||||||
else if(strcasecmp(name, "wayfire") == 0)
|
else if(ffStrEqualsIgnCase(name, "wayfire"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WAYFIRE);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WAYFIRE);
|
||||||
else if(strcasecmp(name, "openbox") == 0)
|
else if(ffStrEqualsIgnCase(name, "openbox"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_OPENBOX);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_OPENBOX);
|
||||||
else if(strcasecmp(name, "xfwm4") == 0)
|
else if(ffStrEqualsIgnCase(name, "xfwm4"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XFWM4);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XFWM4);
|
||||||
else if(strcasecmp(name, "Marco") == 0 ||
|
else if(ffStrEqualsIgnCase(name, "Marco") ||
|
||||||
strcasecmp(name, "Metacity (Marco)") == 0)
|
ffStrEqualsIgnCase(name, "Metacity (Marco)"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MARCO);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MARCO);
|
||||||
else if(strcasecmp(name, "xmonad") == 0)
|
else if(ffStrEqualsIgnCase(name, "xmonad"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XMONAD);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XMONAD);
|
||||||
else if(strcasecmp(name, "WSLg") == 0)
|
else if(ffStrEqualsIgnCase(name, "WSLg"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WSLG);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WSLG);
|
||||||
else if(strcasecmp(name, "dwm") == 0)
|
else if(ffStrEqualsIgnCase(name, "dwm"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DWM);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DWM);
|
||||||
else if(strcasecmp(name, "bspwm") == 0)
|
else if(ffStrEqualsIgnCase(name, "bspwm"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_BSPWM);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_BSPWM);
|
||||||
else if(strcasecmp(name, "tinywm") == 0)
|
else if(ffStrEqualsIgnCase(name, "tinywm"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_TINYWM);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_TINYWM);
|
||||||
else if(strcasecmp(name, "qtile") == 0)
|
else if(ffStrEqualsIgnCase(name, "qtile"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_QTILE);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_QTILE);
|
||||||
else if(strcasecmp(name, "herbstluftwm") == 0)
|
else if(ffStrEqualsIgnCase(name, "herbstluftwm"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM);
|
||||||
else if(strcasecmp(name, "icewm") == 0)
|
else if(ffStrEqualsIgnCase(name, "icewm"))
|
||||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
|
||||||
|
else if(ffStrEqualsIgnCase(name, "dtwm"))
|
||||||
|
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
|
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
|
||||||
@@ -136,10 +146,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "KDE") == 0 ||
|
ffStrEqualsIgnCase(name, "KDE") ||
|
||||||
strcasecmp(name, "plasma") == 0 ||
|
ffStrEqualsIgnCase(name, "plasma") ||
|
||||||
strcasecmp(name, "plasmashell") == 0 ||
|
ffStrEqualsIgnCase(name, "plasmashell") ||
|
||||||
strcasecmp(name, "plasmawayland") == 0
|
ffStrEqualsIgnCase(name, "plasmawayland")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
|
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
|
||||||
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
|
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
|
||||||
@@ -147,10 +157,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "Gnome") == 0 ||
|
ffStrEqualsIgnCase(name, "Gnome") ||
|
||||||
strcasecmp(name, "ubuntu:GNOME") == 0 ||
|
ffStrEqualsIgnCase(name, "ubuntu:GNOME") ||
|
||||||
strcasecmp(name, "ubuntu") == 0 ||
|
ffStrEqualsIgnCase(name, "ubuntu") ||
|
||||||
strcasecmp(name, "gnome-shell") == 0
|
ffStrEqualsIgnCase(name, "gnome-shell")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
|
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
|
||||||
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
|
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
|
||||||
@@ -161,37 +171,37 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "X-Cinnamon") == 0 ||
|
ffStrEqualsIgnCase(name, "X-Cinnamon") ||
|
||||||
strcasecmp(name, "Cinnamon") == 0
|
ffStrEqualsIgnCase(name, "Cinnamon")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetS(&result->deProcessName, "cinnamon");
|
ffStrbufSetS(&result->deProcessName, "cinnamon");
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "XFCE") == 0 ||
|
ffStrEqualsIgnCase(name, "XFCE") ||
|
||||||
strcasecmp(name, "X-XFCE") == 0 ||
|
ffStrEqualsIgnCase(name, "X-XFCE") ||
|
||||||
strcasecmp(name, "XFCE4") == 0 ||
|
ffStrEqualsIgnCase(name, "XFCE4") ||
|
||||||
strcasecmp(name, "X-XFCE4") == 0 ||
|
ffStrEqualsIgnCase(name, "X-XFCE4") ||
|
||||||
strcasecmp(name, "xfce4-session") == 0
|
ffStrEqualsIgnCase(name, "xfce4-session")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetS(&result->deProcessName, "xfce4-session");
|
ffStrbufSetS(&result->deProcessName, "xfce4-session");
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "MATE") == 0 ||
|
ffStrEqualsIgnCase(name, "MATE") ||
|
||||||
strcasecmp(name, "X-MATE") == 0 ||
|
ffStrEqualsIgnCase(name, "X-MATE") ||
|
||||||
strcasecmp(name, "mate-session") == 0
|
ffStrEqualsIgnCase(name, "mate-session")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetS(&result->deProcessName, "mate-session");
|
ffStrbufSetS(&result->deProcessName, "mate-session");
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "LXQt") == 0 ||
|
ffStrEqualsIgnCase(name, "LXQt") ||
|
||||||
strcasecmp(name, "X-LXQT") == 0 ||
|
ffStrEqualsIgnCase(name, "X-LXQT") ||
|
||||||
strcasecmp(name, "lxqt-session") == 0
|
ffStrEqualsIgnCase(name, "lxqt-session")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
|
||||||
@@ -201,14 +211,21 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "Budgie") == 0 ||
|
ffStrEqualsIgnCase(name, "Budgie") ||
|
||||||
strcasecmp(name, "X-Budgie") == 0 ||
|
ffStrEqualsIgnCase(name, "X-Budgie") ||
|
||||||
strcasecmp(name, "budgie-desktop") == 0 ||
|
ffStrEqualsIgnCase(name, "budgie-desktop") ||
|
||||||
strcasecmp(name, "Budgie:GNOME") == 0
|
ffStrEqualsIgnCase(name, "Budgie:GNOME")
|
||||||
) {
|
) {
|
||||||
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
|
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(
|
||||||
|
ffStrEqualsIgnCase(name, "dtsession")
|
||||||
|
) {
|
||||||
|
ffStrbufSetS(&result->deProcessName, "dtsession");
|
||||||
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CDE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
||||||
@@ -219,9 +236,9 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
|||||||
const char* env = getenv("XDG_SESSION_TYPE");
|
const char* env = getenv("XDG_SESSION_TYPE");
|
||||||
if(ffStrSet(env))
|
if(ffStrSet(env))
|
||||||
{
|
{
|
||||||
if(strcasecmp(env, "x11") == 0)
|
if(ffStrEqualsIgnCase(env, "x11"))
|
||||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||||
else if(strcasecmp(env, "tty") == 0)
|
else if(ffStrEqualsIgnCase(env, "tty"))
|
||||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
|
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
|
||||||
else
|
else
|
||||||
ffStrbufSetS(&result->wmProtocolName, env);
|
ffStrbufSetS(&result->wmProtocolName, env);
|
||||||
@@ -237,30 +254,56 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
env = getenv("TERM");
|
env = getenv("TERM");
|
||||||
if(ffStrSet(env) && strcasecmp(env, "linux") == 0)
|
if(ffStrSet(env) && ffStrEqualsIgnCase(env, "linux"))
|
||||||
{
|
{
|
||||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
|
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getFromProcDir(FFDisplayServerResult* result)
|
static const char* getFromProcesses(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
DIR* proc = opendir("/proc");
|
uint32_t userId = getuid();
|
||||||
if(proc == NULL)
|
|
||||||
return;
|
#ifdef __FreeBSD__
|
||||||
|
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, (int) userId};
|
||||||
|
size_t length = 0;
|
||||||
|
|
||||||
|
if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0)
|
||||||
|
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, NULL) failed";
|
||||||
|
|
||||||
|
FF_AUTO_FREE struct kinfo_proc* procs = (struct kinfo_proc*) malloc(length);
|
||||||
|
if(sysctl(request, sizeof(request) / sizeof(*request), procs, &length, NULL, 0) != 0)
|
||||||
|
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, procs) failed";
|
||||||
|
|
||||||
|
length /= sizeof(*procs);
|
||||||
|
|
||||||
|
for (struct kinfo_proc* proc = procs; proc < procs + length; ++proc)
|
||||||
|
{
|
||||||
|
if(result->dePrettyName.length == 0)
|
||||||
|
applyPrettyNameIfDE(result, proc->ki_comm);
|
||||||
|
|
||||||
|
if(result->wmPrettyName.length == 0)
|
||||||
|
applyNameIfWM(result, proc->ki_comm);
|
||||||
|
|
||||||
|
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
|
||||||
|
if(procdir == NULL)
|
||||||
|
return "opendir(\"/proc\") failed";
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64);
|
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64);
|
||||||
ffStrbufAppendS(&procPath, "/proc/");
|
ffStrbufAppendS(&procPath, "/proc/");
|
||||||
|
|
||||||
uint32_t procPathLength = procPath.length;
|
uint32_t procPathLength = procPath.length;
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY userID = ffStrbufCreateF("%i", getuid());
|
|
||||||
FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate();
|
||||||
FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome)
|
FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome)
|
||||||
|
|
||||||
struct dirent* dirent;
|
struct dirent* dirent;
|
||||||
while((dirent = readdir(proc)) != NULL)
|
while((dirent = readdir(procdir)) != NULL)
|
||||||
{
|
{
|
||||||
//Match only folders starting with a number (the pid folders)
|
//Match only folders starting with a number (the pid folders)
|
||||||
if(dirent->d_type != DT_DIR || !isdigit(dirent->d_name[0]))
|
if(dirent->d_type != DT_DIR || !isdigit(dirent->d_name[0]))
|
||||||
@@ -272,7 +315,7 @@ static void getFromProcDir(FFDisplayServerResult* result)
|
|||||||
//Don't check for processes not owend by the current user.
|
//Don't check for processes not owend by the current user.
|
||||||
ffStrbufAppendS(&procPath, "/loginuid");
|
ffStrbufAppendS(&procPath, "/loginuid");
|
||||||
ffReadFileBuffer(procPath.chars, &loginuid);
|
ffReadFileBuffer(procPath.chars, &loginuid);
|
||||||
if(ffStrbufComp(&userID, &loginuid) != 0)
|
if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
|
||||||
{
|
{
|
||||||
ffStrbufSubstrBefore(&procPath, procPathLength);
|
ffStrbufSubstrBefore(&procPath, procPathLength);
|
||||||
continue;
|
continue;
|
||||||
@@ -297,8 +340,9 @@ static void getFromProcDir(FFDisplayServerResult* result)
|
|||||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
closedir(proc);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffdsDetectWMDE(FFDisplayServerResult* result)
|
void ffdsDetectWMDE(FFDisplayServerResult* result)
|
||||||
@@ -338,7 +382,7 @@ void ffdsDetectWMDE(FFDisplayServerResult* result)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//Get missing WM / DE from processes.
|
//Get missing WM / DE from processes.
|
||||||
getFromProcDir(result);
|
getFromProcesses(result);
|
||||||
|
|
||||||
//Return if both wm and de are set, or if env doesn't contain anything
|
//Return if both wm and de are set, or if env doesn't contain anything
|
||||||
if(
|
if(
|
||||||
|
|||||||
@@ -9,20 +9,26 @@
|
|||||||
static double detectGpuTemp(const FFstrbuf* gpuName)
|
static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||||
{
|
{
|
||||||
double result = 0;
|
double result = 0;
|
||||||
const char* error;
|
const char* error = NULL;
|
||||||
|
|
||||||
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
|
if (ffStrbufStartsWithS(gpuName, "Apple M"))
|
||||||
error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result);
|
{
|
||||||
else if(ffStrbufStartsWithS(gpuName, "Apple M2"))
|
switch (strtol(gpuName->chars + strlen("Apple M"), NULL, 10))
|
||||||
error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result);
|
{
|
||||||
else if(ffStrbufStartsWithS(gpuName, "Intel"))
|
case 1: error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result); break;
|
||||||
|
case 2: error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result); break;
|
||||||
|
case 3: error = ffDetectCoreTemps(FF_TEMP_GPU_M3X, &result); break;
|
||||||
|
default: error = "Unsupported Apple Silicon GPU";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ffStrbufStartsWithS(gpuName, "Intel"))
|
||||||
error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result);
|
error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result);
|
||||||
else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
|
else if (ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
|
||||||
error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result);
|
error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result);
|
||||||
else
|
else
|
||||||
error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result);
|
error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result);
|
||||||
|
|
||||||
if(error)
|
if (error)
|
||||||
return FF_GPU_TEMP_UNSET;
|
return FF_GPU_TEMP_UNSET;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -16,7 +16,16 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
|||||||
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
|
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
|
||||||
return "Failed to read host_statistics64";
|
return "Failed to read host_statistics64";
|
||||||
|
|
||||||
ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * instance.state.platform.pageSize;
|
// https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56
|
||||||
|
ram->bytesUsed = ((uint64_t)
|
||||||
|
+ vmstat.active_count
|
||||||
|
+ vmstat.inactive_count
|
||||||
|
+ vmstat.speculative_count
|
||||||
|
+ vmstat.wire_count
|
||||||
|
+ vmstat.compressor_page_count
|
||||||
|
- vmstat.purgeable_count
|
||||||
|
- vmstat.external_page_count
|
||||||
|
) * instance.state.platform.pageSize;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,33 +13,43 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
|||||||
buf[nRead] = '\0';
|
buf[nRead] = '\0';
|
||||||
|
|
||||||
uint64_t memTotal = 0,
|
uint64_t memTotal = 0,
|
||||||
|
memAvailable = 0,
|
||||||
shmem = 0,
|
shmem = 0,
|
||||||
memFree = 0,
|
memFree = 0,
|
||||||
buffers = 0,
|
buffers = 0,
|
||||||
cached = 0,
|
cached = 0,
|
||||||
sReclaimable = 0;
|
sReclaimable = 0;
|
||||||
|
|
||||||
char *token = NULL;
|
char *token = NULL;
|
||||||
if((token = strstr(buf, "MemTotal:")) != NULL)
|
if((token = strstr(buf, "MemTotal:")) != NULL)
|
||||||
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
|
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
|
||||||
|
else
|
||||||
|
return "MemTotal not found in /proc/meminfo";
|
||||||
|
|
||||||
if((token = strstr(buf, "MemFree:")) != NULL)
|
if((token = strstr(buf, "MemAvailable:")) != NULL)
|
||||||
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
|
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((token = strstr(buf, "MemFree:")) != NULL)
|
||||||
|
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
|
||||||
|
|
||||||
if((token = strstr(buf, "Buffers:")) != NULL)
|
if((token = strstr(buf, "Buffers:")) != NULL)
|
||||||
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
|
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
|
||||||
|
|
||||||
if((token = strstr(buf, "Cached:")) != NULL)
|
if((token = strstr(buf, "Cached:")) != NULL)
|
||||||
cached = strtoul(token + strlen("Cached:"), NULL, 10);
|
cached = strtoul(token + strlen("Cached:"), NULL, 10);
|
||||||
|
|
||||||
if((token = strstr(buf, "Shmem:")) != NULL)
|
if((token = strstr(buf, "Shmem:")) != NULL)
|
||||||
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
|
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
|
||||||
|
|
||||||
if((token = strstr(buf, "SReclaimable:")) != NULL)
|
if((token = strstr(buf, "SReclaimable:")) != NULL)
|
||||||
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
|
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
|
||||||
|
|
||||||
|
memAvailable = memFree + buffers + cached + sReclaimable - shmem;
|
||||||
|
}
|
||||||
|
|
||||||
ram->bytesTotal = memTotal * 1024lu;
|
ram->bytesTotal = memTotal * 1024lu;
|
||||||
ram->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * 1024lu;
|
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "packages.h"
|
||||||
|
|
||||||
|
#include "common/settings.h"
|
||||||
|
|
||||||
|
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
|
||||||
|
{
|
||||||
|
result->pkg = (uint32_t) ffSettingsGetSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages");
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
||||||
{
|
{
|
||||||
DIR* dirp = opendir(dirname);
|
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
|
||||||
if(dirp == NULL)
|
if(dirp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -26,8 +26,6 @@ static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
|||||||
if(type == DT_DIR && num_elements >= 2)
|
if(type == DT_DIR && num_elements >= 2)
|
||||||
num_elements -= 2; // accounting for . and ..
|
num_elements -= 2; // accounting for . and ..
|
||||||
|
|
||||||
closedir(dirp);
|
|
||||||
|
|
||||||
return num_elements;
|
return num_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,26 +40,19 @@ static uint32_t getNumElements(FFstrbuf* baseDir, const char* dirname, unsigned
|
|||||||
|
|
||||||
static uint32_t getNumStringsImpl(const char* filename, const char* needle)
|
static uint32_t getNumStringsImpl(const char* filename, const char* needle)
|
||||||
{
|
{
|
||||||
FILE* file = fopen(filename, "r");
|
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
|
||||||
if(file == NULL)
|
if (!ffReadFileBuffer(filename, &content))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
char *iter = content.chars;
|
||||||
char* line = NULL;
|
size_t needleLength = strlen(needle);
|
||||||
size_t len = 0;
|
while ((iter = memmem(iter, content.length - (size_t)(iter - content.chars), needle, needleLength)) != NULL)
|
||||||
|
|
||||||
while(getline(&line, &len, file) != EOF)
|
|
||||||
{
|
{
|
||||||
if(strstr(line, needle) != NULL)
|
++count;
|
||||||
++count;
|
iter += needleLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(line != NULL)
|
|
||||||
free(line);
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,9 +263,8 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts)
|
|||||||
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
|
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
|
||||||
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
|
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
|
||||||
packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
|
packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
|
||||||
packageCounts->pkg += getSQLite3Int(baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages");
|
|
||||||
packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
|
packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
|
||||||
packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages");
|
packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages");
|
||||||
packageCounts->snap += getSnap(baseDir);
|
packageCounts->snap += getSnap(baseDir);
|
||||||
packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
|
packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
|
||||||
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
|
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
|
||||||
@@ -288,7 +278,7 @@ static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* package
|
|||||||
getPackageCounts(baseDir, packageCounts);
|
getPackageCounts(baseDir, packageCounts);
|
||||||
|
|
||||||
uint32_t baseDirLength = baseDir->length;
|
uint32_t baseDirLength = baseDir->length;
|
||||||
ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC"/pacman-mirrors.conf");
|
ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC "/pacman-mirrors.conf");
|
||||||
if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0)
|
if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0)
|
||||||
ffStrbufAppendS(&packageCounts->pacmanBranch, "stable");
|
ffStrbufAppendS(&packageCounts->pacmanBranch, "stable");
|
||||||
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include "fastfetch.h"
|
||||||
|
|
||||||
|
typedef enum FFPhysicalDiskType
|
||||||
|
{
|
||||||
|
FF_PHYSICALDISK_TYPE_NONE = 0,
|
||||||
|
|
||||||
|
// If neither is set, it's unknown
|
||||||
|
FF_PHYSICALDISK_TYPE_HDD = 1 << 0,
|
||||||
|
FF_PHYSICALDISK_TYPE_SSD = 1 << 1,
|
||||||
|
|
||||||
|
FF_PHYSICALDISK_TYPE_FIXED = 1 << 2,
|
||||||
|
FF_PHYSICALDISK_TYPE_REMOVABLE = 1 << 3,
|
||||||
|
} FFPhysicalDiskType;
|
||||||
|
|
||||||
|
typedef struct FFPhysicalDiskResult
|
||||||
|
{
|
||||||
|
FFstrbuf name;
|
||||||
|
FFstrbuf interconnect;
|
||||||
|
FFstrbuf serial;
|
||||||
|
FFstrbuf devPath;
|
||||||
|
FFPhysicalDiskType type;
|
||||||
|
uint64_t size;
|
||||||
|
} FFPhysicalDiskResult;
|
||||||
|
|
||||||
|
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options);
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#include "physicaldisk.h"
|
||||||
|
#include "util/apple/cf_helpers.h"
|
||||||
|
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/IOBSD.h>
|
||||||
|
#include <IOKit/storage/IOMedia.h>
|
||||||
|
#include <IOKit/storage/IOBlockStorageDriver.h>
|
||||||
|
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
|
||||||
|
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
|
||||||
|
|
||||||
|
static inline void wrapIoObjectRelease(io_service_t* service)
|
||||||
|
{
|
||||||
|
assert(service);
|
||||||
|
if (*service)
|
||||||
|
IOObjectRelease(*service);
|
||||||
|
}
|
||||||
|
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
|
||||||
|
|
||||||
|
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
|
||||||
|
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
|
||||||
|
return "IOServiceGetMatchingServices() failed";
|
||||||
|
|
||||||
|
io_registry_entry_t registryEntry;
|
||||||
|
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||||
|
{
|
||||||
|
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
|
||||||
|
|
||||||
|
io_name_t deviceName;
|
||||||
|
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
|
||||||
|
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||||
|
ffStrbufInit(&device->serial);
|
||||||
|
ffStrbufInitS(&device->name, deviceName);
|
||||||
|
ffStrbufInit(&device->devPath);
|
||||||
|
ffStrbufInit(&device->interconnect);
|
||||||
|
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||||
|
device->size = 0;
|
||||||
|
|
||||||
|
FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions);
|
||||||
|
device->type |= CFBooleanGetValue(removable) ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||||
|
|
||||||
|
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
|
||||||
|
if (bsdName)
|
||||||
|
{
|
||||||
|
ffCfStrGetString(bsdName, &device->devPath);
|
||||||
|
ffStrbufPrependS(&device->devPath, "/dev/");
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
|
||||||
|
if (mediaSize)
|
||||||
|
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
|
||||||
|
else
|
||||||
|
device->size = 0;
|
||||||
|
|
||||||
|
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
|
||||||
|
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
||||||
|
if (protocolCharacteristics)
|
||||||
|
ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectTypeKey), &device->interconnect);
|
||||||
|
|
||||||
|
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
||||||
|
if (deviceCharacteristics)
|
||||||
|
{
|
||||||
|
ffCfDictGetString(deviceCharacteristics, CFSTR(kIOPropertyProductSerialNumberKey), &device->serial);
|
||||||
|
|
||||||
|
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
|
||||||
|
if (mediumType)
|
||||||
|
{
|
||||||
|
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
|
||||||
|
device->type |= FF_PHYSICALDISK_TYPE_SSD;
|
||||||
|
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
|
||||||
|
device->type |= FF_PHYSICALDISK_TYPE_HDD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#include "physicaldisk.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
|
#include <devstat.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/disk.h>
|
||||||
|
#include <libgeom.h>
|
||||||
|
|
||||||
|
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
struct gmesh geomTree;
|
||||||
|
if (geom_gettree(&geomTree) < 0)
|
||||||
|
return "geom_gettree() failed";
|
||||||
|
|
||||||
|
if (geom_stats_open() < 0)
|
||||||
|
return "geom_stats_open() failed";
|
||||||
|
|
||||||
|
void* snap = geom_stats_snapshot_get();
|
||||||
|
struct devstat* snapIter;
|
||||||
|
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
|
||||||
|
{
|
||||||
|
if (snapIter->device_type & DEVSTAT_TYPE_PASS)
|
||||||
|
continue;
|
||||||
|
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
|
||||||
|
if (geomId == NULL)
|
||||||
|
continue;
|
||||||
|
if (geomId->lg_what != ISPROVIDER)
|
||||||
|
continue;
|
||||||
|
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
|
||||||
|
if (provider->lg_geom->lg_rank != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
|
||||||
|
FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate();
|
||||||
|
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
|
||||||
|
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
|
||||||
|
{
|
||||||
|
if (ffStrEquals(ptr->lg_name, "descr"))
|
||||||
|
ffStrbufSetS(&name, ptr->lg_val);
|
||||||
|
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
|
||||||
|
type |= ffStrEquals(ptr->lg_val, "0") ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
|
||||||
|
else if (ffStrEquals(ptr->lg_name, "ident"))
|
||||||
|
ffStrbufSetS(&identifier, ptr->lg_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||||
|
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
|
||||||
|
ffStrbufInitMove(&device->serial, &identifier);
|
||||||
|
ffStrbufInit(&device->interconnect);
|
||||||
|
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
|
||||||
|
{
|
||||||
|
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
|
||||||
|
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
|
||||||
|
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
|
||||||
|
}
|
||||||
|
device->size = (uint64_t) provider->lg_mediasize;
|
||||||
|
ffStrbufInitMove(&device->name, &name);
|
||||||
|
device->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
geom_stats_snapshot_free(snap);
|
||||||
|
geom_stats_close();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
#include "physicaldisk.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
|
#include "common/properties.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
|
||||||
|
if(sysBlockDirp == NULL)
|
||||||
|
return "opendir(\"/sys/block/\") == NULL";
|
||||||
|
|
||||||
|
struct dirent* sysBlockEntry;
|
||||||
|
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
|
||||||
|
{
|
||||||
|
const char* const devName = sysBlockEntry->d_name;
|
||||||
|
|
||||||
|
if (devName[0] == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char pathSysBlock[PATH_MAX];
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
|
||||||
|
|
||||||
|
char pathSysDeviceReal[PATH_MAX];
|
||||||
|
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
|
||||||
|
if (pathLength < 0)
|
||||||
|
continue;
|
||||||
|
pathSysDeviceReal[pathLength] = '\0';
|
||||||
|
|
||||||
|
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
|
||||||
|
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||||
|
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||||
|
ffStrbufInit(&device->name);
|
||||||
|
|
||||||
|
{
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||||
|
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||||
|
if (device->name.length > 0)
|
||||||
|
ffStrbufAppendC(&device->name, ' ');
|
||||||
|
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||||
|
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||||
|
ffStrbufTrim(&device->name, ' ');
|
||||||
|
|
||||||
|
if (device->name.length == 0)
|
||||||
|
ffStrbufSetS(&device->name, devName);
|
||||||
|
|
||||||
|
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||||
|
{
|
||||||
|
ffStrbufDestroy(&device->name);
|
||||||
|
result->length--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||||
|
|
||||||
|
{
|
||||||
|
ffStrbufInit(&device->interconnect);
|
||||||
|
if (strstr(pathSysDeviceReal, "/usb") != NULL)
|
||||||
|
ffStrbufSetS(&device->interconnect, "usb");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName);
|
||||||
|
if (!ffAppendFileBuffer(pathSysBlock, &device->interconnect))
|
||||||
|
{
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/uevent", devName);
|
||||||
|
if (ffParsePropFile(pathSysBlock, "DEVTYPE=", &device->interconnect))
|
||||||
|
ffStrbufSubstrBeforeLastC(&device->interconnect, '_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
|
||||||
|
char isRotationalChar = '1';
|
||||||
|
if (ffReadFileData(pathSysBlock, 1, &isRotationalChar) > 0)
|
||||||
|
device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
|
||||||
|
char blkSize[32];
|
||||||
|
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize);
|
||||||
|
if (fileSize > 0)
|
||||||
|
{
|
||||||
|
blkSize[fileSize] = 0;
|
||||||
|
device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
device->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char removableChar = '0';
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName);
|
||||||
|
if (ffReadFileData(pathSysBlock, 1, &removableChar) > 0)
|
||||||
|
device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ffStrbufInit(&device->serial);
|
||||||
|
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName);
|
||||||
|
ffReadFileBuffer(pathSysBlock, &device->serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
#include "physicaldisk.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
|
#include "util/windows/unicode.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winioctl.h>
|
||||||
|
|
||||||
|
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
|
||||||
|
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
|
||||||
|
for (uint32_t idev = 0; ; ++idev)
|
||||||
|
{
|
||||||
|
_ultow(idev, pNum, 10);
|
||||||
|
|
||||||
|
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (hDevice == INVALID_HANDLE_VALUE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DWORD retSize;
|
||||||
|
char sddBuffer[4096];
|
||||||
|
if(!DeviceIoControl(
|
||||||
|
hDevice,
|
||||||
|
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||||
|
&(STORAGE_PROPERTY_QUERY) {
|
||||||
|
.PropertyId = StorageDeviceProperty,
|
||||||
|
.QueryType = PropertyStandardQuery,
|
||||||
|
},
|
||||||
|
sizeof(STORAGE_PROPERTY_QUERY),
|
||||||
|
&sddBuffer,
|
||||||
|
sizeof(sddBuffer),
|
||||||
|
&retSize,
|
||||||
|
NULL
|
||||||
|
) || retSize == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||||
|
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||||
|
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||||
|
|
||||||
|
ffStrbufInit(&device->name);
|
||||||
|
if (sdd->VendorIdOffset != 0)
|
||||||
|
{
|
||||||
|
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
|
||||||
|
ffStrbufTrim(&device->name, ' ');
|
||||||
|
}
|
||||||
|
if (sdd->ProductIdOffset != 0)
|
||||||
|
{
|
||||||
|
if (device->name.length)
|
||||||
|
ffStrbufAppendC(&device->name, ' ');
|
||||||
|
|
||||||
|
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||||
|
ffStrbufTrimRight(&device->name, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||||
|
{
|
||||||
|
ffStrbufDestroy(&device->name);
|
||||||
|
result->length--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufInitWS(&device->devPath, szDevice);
|
||||||
|
ffStrbufInit(&device->serial);
|
||||||
|
if (sdd->SerialNumberOffset != 0)
|
||||||
|
{
|
||||||
|
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
|
||||||
|
ffStrbufTrim(&device->serial, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
device->type |= sdd->RemovableMedia ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||||
|
|
||||||
|
ffStrbufInit(&device->interconnect);
|
||||||
|
switch (sdd->BusType)
|
||||||
|
{
|
||||||
|
case BusTypeUnknown: ffStrbufSetStatic(&device->interconnect, "Unknown"); break;
|
||||||
|
case BusTypeScsi: ffStrbufSetStatic(&device->interconnect, "Scsi"); break;
|
||||||
|
case BusTypeAtapi: ffStrbufSetStatic(&device->interconnect, "Atapi"); break;
|
||||||
|
case BusTypeAta: ffStrbufSetStatic(&device->interconnect, "Ata"); break;
|
||||||
|
case BusType1394: ffStrbufSetStatic(&device->interconnect, "1394"); break;
|
||||||
|
case BusTypeSsa: ffStrbufSetStatic(&device->interconnect, "Ssa"); break;
|
||||||
|
case BusTypeFibre: ffStrbufSetStatic(&device->interconnect, "Fibra"); break;
|
||||||
|
case BusTypeUsb: ffStrbufSetStatic(&device->interconnect, "Usb"); break;
|
||||||
|
case BusTypeRAID: ffStrbufSetStatic(&device->interconnect, "RAID"); break;
|
||||||
|
case BusTypeiScsi: ffStrbufSetStatic(&device->interconnect, "iScsi"); break;
|
||||||
|
case BusTypeSas: ffStrbufSetStatic(&device->interconnect, "Sas"); break;
|
||||||
|
case BusTypeSata: ffStrbufSetStatic(&device->interconnect, "Sata"); break;
|
||||||
|
case BusTypeSd: ffStrbufSetStatic(&device->interconnect, "Sd"); break;
|
||||||
|
case BusTypeMmc: ffStrbufSetStatic(&device->interconnect, "Mmc"); break;
|
||||||
|
case BusTypeVirtual: ffStrbufSetStatic(&device->interconnect, "Virtual"); break;
|
||||||
|
case BusTypeFileBackedVirtual: ffStrbufSetStatic(&device->interconnect, "FileBackedVirtual"); break;
|
||||||
|
case BusTypeSpaces: ffStrbufSetStatic(&device->interconnect, "Spaces"); break;
|
||||||
|
case BusTypeNvme: ffStrbufSetStatic(&device->interconnect, "Nvme"); break;
|
||||||
|
case BusTypeSCM: ffStrbufSetStatic(&device->interconnect, "SCM"); break;
|
||||||
|
case BusTypeUfs: ffStrbufSetStatic(&device->interconnect, "Ufs"); break;
|
||||||
|
default: ffStrbufSetF(&device->interconnect, "Unknown (%d)", (int) sdd->BusType); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
|
||||||
|
if(DeviceIoControl(
|
||||||
|
hDevice,
|
||||||
|
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||||
|
&(STORAGE_PROPERTY_QUERY) {
|
||||||
|
.PropertyId = StorageDeviceSeekPenaltyProperty,
|
||||||
|
.QueryType = PropertyStandardQuery,
|
||||||
|
},
|
||||||
|
sizeof(STORAGE_PROPERTY_QUERY),
|
||||||
|
&dspd,
|
||||||
|
sizeof(dspd),
|
||||||
|
&retSize,
|
||||||
|
NULL
|
||||||
|
) && retSize == sizeof(dspd))
|
||||||
|
device->type |= dspd.IncursSeekPenalty ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
|
||||||
|
|
||||||
|
DISK_GEOMETRY_EX dge = {};
|
||||||
|
if(DeviceIoControl(
|
||||||
|
hDevice,
|
||||||
|
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&dge,
|
||||||
|
sizeof(dge),
|
||||||
|
&retSize,
|
||||||
|
NULL))
|
||||||
|
device->size = (uint64_t) dge.DiskSize.QuadPart;
|
||||||
|
else
|
||||||
|
device->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -333,6 +333,25 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
|
|||||||
count += detectTemp(conn, "Tp09", result); // CPU core 8
|
count += detectTemp(conn, "Tp09", result); // CPU core 8
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FF_TEMP_CPU_M3X:
|
||||||
|
count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
|
||||||
|
count += detectTemp(conn, "Te0L", result); // CPU efficiency core 2
|
||||||
|
count += detectTemp(conn, "Te0P", result); // CPU efficiency core 3
|
||||||
|
count += detectTemp(conn, "Te0S", result); // CPU efficiency core 4
|
||||||
|
count += detectTemp(conn, "Tf04", result); // CPU performance core 1
|
||||||
|
count += detectTemp(conn, "Tf09", result); // CPU performance core 2
|
||||||
|
count += detectTemp(conn, "Tf0A", result); // CPU performance core 3
|
||||||
|
count += detectTemp(conn, "Tf0B", result); // CPU performance core 4
|
||||||
|
count += detectTemp(conn, "Tf0D", result); // CPU performance core 5
|
||||||
|
count += detectTemp(conn, "Tf0E", result); // CPU performance core 6
|
||||||
|
count += detectTemp(conn, "Tf44", result); // CPU performance core 7
|
||||||
|
count += detectTemp(conn, "Tf49", result); // CPU performance core 8
|
||||||
|
count += detectTemp(conn, "Tf4A", result); // CPU performance core 9
|
||||||
|
count += detectTemp(conn, "Tf4B", result); // CPU performance core 10
|
||||||
|
count += detectTemp(conn, "Tf4D", result); // CPU performance core 11
|
||||||
|
count += detectTemp(conn, "Tf4E", result); // CPU performance core 12
|
||||||
|
break;
|
||||||
|
|
||||||
case FF_TEMP_GPU_INTEL:
|
case FF_TEMP_GPU_INTEL:
|
||||||
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
|
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
|
||||||
goto gpu_unknown;
|
goto gpu_unknown;
|
||||||
@@ -359,12 +378,27 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
|
|||||||
count += detectTemp(conn, "Tg0j", result); // GPU 2
|
count += detectTemp(conn, "Tg0j", result); // GPU 2
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FF_TEMP_GPU_M3X:
|
||||||
|
count += detectTemp(conn, "Tf14", result); // GPU 1
|
||||||
|
count += detectTemp(conn, "Tf18", result); // GPU 2
|
||||||
|
count += detectTemp(conn, "Tf19", result); // GPU 3
|
||||||
|
count += detectTemp(conn, "Tf1A", result); // GPU 4
|
||||||
|
count += detectTemp(conn, "Tf24", result); // GPU 5
|
||||||
|
count += detectTemp(conn, "Tf28", result); // GPU 6
|
||||||
|
count += detectTemp(conn, "Tf29", result); // GPU 7
|
||||||
|
count += detectTemp(conn, "Tf2A", result); // GPU 8
|
||||||
|
break;
|
||||||
|
|
||||||
case FF_TEMP_BATTERY:
|
case FF_TEMP_BATTERY:
|
||||||
count += detectTemp(conn, "TB1T", result); // Battery
|
count += detectTemp(conn, "TB1T", result); // Battery
|
||||||
|
count += detectTemp(conn, "TB2T", result); // Battery
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FF_TEMP_MEMORY:
|
case FF_TEMP_MEMORY:
|
||||||
count += detectTemp(conn, "Tm02", result); // Memory
|
count += detectTemp(conn, "Tm02", result); // Memory 1
|
||||||
|
count += detectTemp(conn, "Tm06", result); // Memory 2
|
||||||
|
count += detectTemp(conn, "Tm08", result); // Memory 3
|
||||||
|
count += detectTemp(conn, "Tm09", result); // Memory 4
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,14 @@ enum FFTempType
|
|||||||
FF_TEMP_CPU_X64,
|
FF_TEMP_CPU_X64,
|
||||||
FF_TEMP_CPU_M1X,
|
FF_TEMP_CPU_M1X,
|
||||||
FF_TEMP_CPU_M2X,
|
FF_TEMP_CPU_M2X,
|
||||||
|
FF_TEMP_CPU_M3X,
|
||||||
|
|
||||||
FF_TEMP_GPU_INTEL,
|
FF_TEMP_GPU_INTEL,
|
||||||
FF_TEMP_GPU_AMD,
|
FF_TEMP_GPU_AMD,
|
||||||
FF_TEMP_GPU_UNKNOWN,
|
FF_TEMP_GPU_UNKNOWN,
|
||||||
FF_TEMP_GPU_M1X,
|
FF_TEMP_GPU_M1X,
|
||||||
FF_TEMP_GPU_M2X,
|
FF_TEMP_GPU_M2X,
|
||||||
|
FF_TEMP_GPU_M3X,
|
||||||
|
|
||||||
FF_TEMP_BATTERY,
|
FF_TEMP_BATTERY,
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#include "util/mallocHelper.h"
|
#include "util/mallocHelper.h"
|
||||||
@@ -162,6 +164,28 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
|
|||||||
NULL
|
NULL
|
||||||
}) == NULL;
|
}) == NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static bool getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||||
|
{
|
||||||
|
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
|
||||||
|
ffStrbufAppendS(&command, "printf \"%s\" \"$");
|
||||||
|
ffStrbufAppendTransformS(&command, exeName, toupper);
|
||||||
|
ffStrbufAppendS(&command, "_VERSION\"");
|
||||||
|
|
||||||
|
if (ffProcessAppendStdOut(version, (char* const[]) {
|
||||||
|
"env",
|
||||||
|
"-i",
|
||||||
|
exe->chars,
|
||||||
|
"-c",
|
||||||
|
command.chars,
|
||||||
|
NULL
|
||||||
|
}) != NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ffStrbufSubstrBeforeFirstC(version, '(');
|
||||||
|
ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||||
@@ -198,7 +222,7 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
|||||||
|
|
||||||
return getFileVersion(exe->chars, version);
|
return getFileVersion(exe->chars, version);
|
||||||
#else
|
#else
|
||||||
return false;
|
return getShellVersionGeneric(exe, exeName, version);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -68,8 +67,6 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
|
|||||||
|
|
||||||
static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
||||||
{
|
{
|
||||||
const char* error = NULL;
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
char statFilePath[64];
|
char statFilePath[64];
|
||||||
@@ -86,20 +83,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
|||||||
!ffStrSet(name) ||
|
!ffStrSet(name) ||
|
||||||
*ppid == 0
|
*ppid == 0
|
||||||
)
|
)
|
||||||
error = "sscanf(stat) failed";
|
return "sscanf(stat) failed";
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
struct proc_bsdshortinfo proc;
|
struct proc_bsdshortinfo proc;
|
||||||
if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0)
|
if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0)
|
||||||
error = "proc_pidinfo(pid) failed";
|
return "proc_pidinfo(pid) failed";
|
||||||
else
|
|
||||||
{
|
|
||||||
*ppid = (pid_t)proc.pbsi_ppid;
|
|
||||||
strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
*ppid = (pid_t)proc.pbsi_ppid;
|
||||||
|
strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
|
||||||
struct kinfo_proc proc;
|
struct kinfo_proc proc;
|
||||||
size_t size = sizeof(proc);
|
size_t size = sizeof(proc);
|
||||||
@@ -108,16 +103,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
|||||||
&proc, &size,
|
&proc, &size,
|
||||||
NULL, 0
|
NULL, 0
|
||||||
))
|
))
|
||||||
error = "sysctl(KERN_PROC_PID) failed";
|
return "sysctl(KERN_PROC_PID) failed";
|
||||||
else
|
|
||||||
{
|
*ppid = (pid_t)proc.ki_ppid;
|
||||||
*ppid = (pid_t)proc.ki_ppid;
|
strncpy(name, proc.ki_comm, COMMLEN);
|
||||||
strncpy(name, proc.ki_comm, COMMLEN);
|
|
||||||
}
|
#else
|
||||||
|
|
||||||
|
return "Unsupported platform";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
|
static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
|
||||||
@@ -286,34 +283,8 @@ static void getUserShellFromEnv(FFTerminalShellResult* result)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
|
||||||
{
|
|
||||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
|
|
||||||
ffStrbufAppendS(&command, "printf \"%s\" \"$");
|
|
||||||
ffStrbufAppendTransformS(&command, exeName, toupper);
|
|
||||||
ffStrbufAppendS(&command, "_VERSION\"");
|
|
||||||
|
|
||||||
ffProcessAppendStdOut(version, (char* const[]) {
|
|
||||||
"env",
|
|
||||||
"-i",
|
|
||||||
exe->chars,
|
|
||||||
"-c",
|
|
||||||
command.chars,
|
|
||||||
NULL
|
|
||||||
});
|
|
||||||
ffStrbufSubstrBeforeFirstC(version, '(');
|
|
||||||
ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||||
|
|
||||||
static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
|
||||||
{
|
|
||||||
ffStrbufClear(version);
|
|
||||||
if(!fftsGetShellVersion(exe, exeName, version))
|
|
||||||
getShellVersionGeneric(exe, exeName, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
||||||
|
|
||||||
const FFTerminalShellResult* ffDetectTerminalShell()
|
const FFTerminalShellResult* ffDetectTerminalShell()
|
||||||
@@ -350,7 +321,8 @@ const FFTerminalShellResult* ffDetectTerminalShell()
|
|||||||
getTerminalFromEnv(&result);
|
getTerminalFromEnv(&result);
|
||||||
getUserShellFromEnv(&result);
|
getUserShellFromEnv(&result);
|
||||||
|
|
||||||
getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
|
ffStrbufClear(&result.shellVersion);
|
||||||
|
fftsGetShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
|
||||||
|
|
||||||
if(ffStrbufEqualS(&result.shellProcessName, "pwsh"))
|
if(ffStrbufEqualS(&result.shellProcessName, "pwsh"))
|
||||||
ffStrbufInitStatic(&result.shellPrettyName, "PowerShell");
|
ffStrbufInitStatic(&result.shellPrettyName, "PowerShell");
|
||||||
|
|||||||
@@ -18,22 +18,22 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result)
|
|||||||
ffStrbufAppendS(result, "Connected");
|
ffStrbufAppendS(result, "Connected");
|
||||||
break;
|
break;
|
||||||
case wlan_interface_state_ad_hoc_network_formed:
|
case wlan_interface_state_ad_hoc_network_formed:
|
||||||
ffStrbufAppendS(result, "First node in a ad hoc network");
|
ffStrbufAppendS(result, "Ad hoc network formed");
|
||||||
break;
|
break;
|
||||||
case wlan_interface_state_disconnecting:
|
case wlan_interface_state_disconnecting:
|
||||||
ffStrbufAppendS(result, "Disconnecting");
|
ffStrbufAppendS(result, "Disconnecting");
|
||||||
break;
|
break;
|
||||||
case wlan_interface_state_disconnected:
|
case wlan_interface_state_disconnected:
|
||||||
ffStrbufAppendS(result, "Not connected");
|
ffStrbufAppendS(result, "Disconnected");
|
||||||
break;
|
break;
|
||||||
case wlan_interface_state_associating:
|
case wlan_interface_state_associating:
|
||||||
ffStrbufAppendS(result, "Attempting to associate with a network");
|
ffStrbufAppendS(result, "Associating");
|
||||||
break;
|
break;
|
||||||
case wlan_interface_state_discovering:
|
case wlan_interface_state_discovering:
|
||||||
ffStrbufAppendS(result, "Auto configuration is discovering settings for the network");
|
ffStrbufAppendS(result, "Discovering");
|
||||||
break;
|
break;
|
||||||
case wlan_interface_state_authenticating:
|
case wlan_interface_state_authenticating:
|
||||||
ffStrbufAppendS(result, "In process of authenticating");
|
ffStrbufAppendS(result, "Authenticating");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ffStrbufAppendS(result, "Unknown");
|
ffStrbufAppendS(result, "Unknown");
|
||||||
@@ -133,16 +133,16 @@ const char* ffDetectWifi(FFlist* result)
|
|||||||
case dot11_phy_type_ht:
|
case dot11_phy_type_ht:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
|
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
|
||||||
break;
|
break;
|
||||||
case 8 /*dot11_phy_type_vht*/:
|
case dot11_phy_type_vht:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
|
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
|
||||||
break;
|
break;
|
||||||
case 9 /*dot11_phy_type_dmg*/:
|
case dot11_phy_type_dmg:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11ad (WiGig)");
|
ffStrbufAppendS(&item->conn.protocol, "802.11ad (WiGig)");
|
||||||
break;
|
break;
|
||||||
case 10 /*dot11_phy_type_he*/:
|
case dot11_phy_type_he:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
|
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
|
||||||
break;
|
break;
|
||||||
case 11 /*dot11_phy_type_eht*/:
|
case dot11_phy_type_eht:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
|
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -179,10 +179,10 @@ const char* ffDetectWifi(FFlist* result)
|
|||||||
case DOT11_AUTH_ALGO_RSNA_PSK:
|
case DOT11_AUTH_ALGO_RSNA_PSK:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA2-PSK");
|
ffStrbufAppendS(&item->conn.security, "WPA2-PSK");
|
||||||
break;
|
break;
|
||||||
case 8 /* DOT11_AUTH_ALGO_WPA3 */:
|
case DOT11_AUTH_ALGO_WPA3:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA3");
|
ffStrbufAppendS(&item->conn.security, "WPA3");
|
||||||
break;
|
break;
|
||||||
case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */:
|
case DOT11_AUTH_ALGO_WPA3_SAE:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA3-SAE");
|
ffStrbufAppendS(&item->conn.security, "WPA3-SAE");
|
||||||
break;
|
break;
|
||||||
case 10 /* DOT11_AUTH_ALGO_OWE */:
|
case 10 /* DOT11_AUTH_ALGO_OWE */:
|
||||||
|
|||||||
+14
-14
@@ -1,16 +1,16 @@
|
|||||||
${c3} ,-^-___
|
${c3} ,-^-___
|
||||||
${c3} /\\\\\\///
|
${c3} /\\\///
|
||||||
${c2}refined.${c1} /\\\\\\\\//
|
${c2}refined.${c1} /\\\\//
|
||||||
${c2}reliable.${c1} /\\\\\\///
|
${c2}reliable.${c1} /\\\///
|
||||||
${c2}ready.${c1} /\\\\/////\\
|
${c2}ready.${c1} /\\/////\
|
||||||
__///\\\\\\\\/////\\
|
__///\\\\/////\
|
||||||
${c3} _//////\\\\\\\\\\\\\\////
|
${c3} _//////\\\\\\\////
|
||||||
${c1} ///////${c3}\\\\\\\\\\\\\\\\\\\\//
|
${c1} ///////${c3}\\\\\\\\\\//
|
||||||
//////${c1}\\\\\\\\\\/
|
//////${c1}\\\\\/
|
||||||
/////\\\\\\\\\\/
|
/////\\\\\/
|
||||||
/////${c3}\\\\\\\\/
|
/////${c3}\\\\/
|
||||||
/\\\\///\\\\\\/
|
/\\///\\\/
|
||||||
/\\\\\\/${c1}\\\/
|
/\\\/${c1}\\/
|
||||||
/\\\\\\\\//
|
/\\\\//
|
||||||
//////
|
//////
|
||||||
/// ${c3}\\\\\\\\\\
|
/// ${c3}\\\\\
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.:-==++++++++++++++++++++++-.
|
||||||
|
.:=+##############################+
|
||||||
|
.=*###################################-
|
||||||
|
:+######################################:
|
||||||
|
:+######################################*-
|
||||||
|
.+#############*+--:::::::::::::::::::::.
|
||||||
|
:*##########*=:
|
||||||
|
-###########=
|
||||||
|
:##########+.
|
||||||
|
*#########=
|
||||||
|
=*********+ .::::::::::::::::.
|
||||||
|
**********. -*###################+:
|
||||||
|
:********** =#######################=
|
||||||
|
-*********+ +************************
|
||||||
|
:*********+ :***********************:
|
||||||
|
.********** .=******************+-
|
||||||
|
+*********-
|
||||||
|
.**********.
|
||||||
|
=**********:
|
||||||
|
+**********=.
|
||||||
|
=***********=:
|
||||||
|
-*************+-.
|
||||||
|
:+****************+++++++++++++++++++++==:
|
||||||
|
:+**************************************+.
|
||||||
|
-+************************************-
|
||||||
|
.-+*********************************.
|
||||||
|
:-==+*************************=.
|
||||||
@@ -1348,6 +1348,15 @@ static const FFlogo E[] = {
|
|||||||
.colorKeys = FF_COLOR_FG_WHITE,
|
.colorKeys = FF_COLOR_FG_WHITE,
|
||||||
.colorTitle = FF_COLOR_FG_WHITE,
|
.colorTitle = FF_COLOR_FG_WHITE,
|
||||||
},
|
},
|
||||||
|
// EshanizedOS
|
||||||
|
{
|
||||||
|
.names = {"EshanizedOS"},
|
||||||
|
.lines = FASTFETCH_DATATEXT_LOGO_ESHANIZEDOS,
|
||||||
|
.colors = {
|
||||||
|
FF_COLOR_FG_RED,
|
||||||
|
FF_COLOR_FG_WHITE,
|
||||||
|
},
|
||||||
|
},
|
||||||
// EuroLinux
|
// EuroLinux
|
||||||
{
|
{
|
||||||
.names = {"EuroLinux"},
|
.names = {"EuroLinux"},
|
||||||
|
|||||||
@@ -17,10 +17,13 @@ FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
|
|||||||
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
|
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||||
|
|
||||||
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||||
.resizeFunc = logoResize,
|
.resizeFunc = logoResize,
|
||||||
.library = imageMagick,
|
.library = imageMagick,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,10 +21,13 @@ FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
|
|||||||
)
|
)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||||
|
|
||||||
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||||
.resizeFunc = logoResize,
|
.resizeFunc = logoResize,
|
||||||
.library = imageMagick,
|
.library = imageMagick,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
#define FF_DISKIO_DISPLAY_NAME "Disk IO"
|
#define FF_DISKIO_DISPLAY_NAME "Disk IO"
|
||||||
#define FF_DISKIO_NUM_FORMAT_ARGS 11
|
#define FF_DISKIO_NUM_FORMAT_ARGS 8
|
||||||
|
|
||||||
static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right)
|
static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right)
|
||||||
{
|
{
|
||||||
@@ -17,10 +17,7 @@ static void formatKey(const FFDiskIOOptions* options, FFDiskIOResult* dev, uint3
|
|||||||
{
|
{
|
||||||
if(options->moduleArgs.key.length == 0)
|
if(options->moduleArgs.key.length == 0)
|
||||||
{
|
{
|
||||||
if(!dev->name.length)
|
ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
|
||||||
ffStrbufSetF(&dev->name, "unknown %u", (unsigned) index);
|
|
||||||
|
|
||||||
ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.chars);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -74,34 +71,15 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
|
|||||||
ffParseSize(dev->bytesWritten, &buffer2);
|
ffParseSize(dev->bytesWritten, &buffer2);
|
||||||
ffStrbufAppendS(&buffer2, "/s");
|
ffStrbufAppendS(&buffer2, "/s");
|
||||||
|
|
||||||
const char* physicalType;
|
|
||||||
switch(dev->type)
|
|
||||||
{
|
|
||||||
case FF_DISKIO_PHYSICAL_TYPE_HDD:
|
|
||||||
physicalType = "HDD";
|
|
||||||
break;
|
|
||||||
case FF_DISKIO_PHYSICAL_TYPE_SSD:
|
|
||||||
physicalType = "SSD";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
physicalType = "Unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
FF_STRBUF_AUTO_DESTROY sizePretty = ffStrbufCreate();
|
|
||||||
ffParseSize(dev->size, &sizePretty);
|
|
||||||
|
|
||||||
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISKIO_NUM_FORMAT_ARGS, (FFformatarg[]){
|
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISKIO_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
|
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
|
||||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2},
|
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2},
|
||||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
||||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
|
|
||||||
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
|
|
||||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
||||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesRead},
|
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesRead},
|
||||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesWritten},
|
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesWritten},
|
||||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->readCount},
|
{FF_FORMAT_ARG_TYPE_UINT64, &dev->readCount},
|
||||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount},
|
{FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount},
|
||||||
{FF_FORMAT_ARG_TYPE_STRBUF, &sizePretty},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
@@ -110,7 +88,6 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
|
|||||||
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
|
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
|
||||||
{
|
{
|
||||||
ffStrbufDestroy(&dev->name);
|
ffStrbufDestroy(&dev->name);
|
||||||
ffStrbufDestroy(&dev->interconnect);
|
|
||||||
ffStrbufDestroy(&dev->devPath);
|
ffStrbufDestroy(&dev->devPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,33 +158,16 @@ void ffGenerateDiskIOJsonResult(FFDiskIOOptions* options, yyjson_mut_doc* doc, y
|
|||||||
{
|
{
|
||||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
|
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
|
||||||
yyjson_mut_obj_add_strbuf(doc, obj, "interconnectType", &dev->interconnect);
|
|
||||||
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
|
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
|
||||||
|
|
||||||
switch(dev->type)
|
|
||||||
{
|
|
||||||
case FF_DISKIO_PHYSICAL_TYPE_HDD:
|
|
||||||
yyjson_mut_obj_add_str(doc, obj, "physicalType", "HDD");
|
|
||||||
break;
|
|
||||||
case FF_DISKIO_PHYSICAL_TYPE_SSD:
|
|
||||||
yyjson_mut_obj_add_str(doc, obj, "physicalType", "SSD");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
yyjson_mut_obj_add_null(doc, obj, "physicalType");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
yyjson_mut_obj_add_uint(doc, obj, "bytesRead", dev->bytesRead);
|
yyjson_mut_obj_add_uint(doc, obj, "bytesRead", dev->bytesRead);
|
||||||
yyjson_mut_obj_add_uint(doc, obj, "bytesWritten", dev->bytesWritten);
|
yyjson_mut_obj_add_uint(doc, obj, "bytesWritten", dev->bytesWritten);
|
||||||
yyjson_mut_obj_add_uint(doc, obj, "readCount", dev->readCount);
|
yyjson_mut_obj_add_uint(doc, obj, "readCount", dev->readCount);
|
||||||
yyjson_mut_obj_add_uint(doc, obj, "writeCount", dev->writeCount);
|
yyjson_mut_obj_add_uint(doc, obj, "writeCount", dev->writeCount);
|
||||||
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
|
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
|
||||||
{
|
{
|
||||||
ffStrbufDestroy(&dev->name);
|
ffStrbufDestroy(&dev->name);
|
||||||
ffStrbufDestroy(&dev->interconnect);
|
|
||||||
ffStrbufDestroy(&dev->devPath);
|
ffStrbufDestroy(&dev->devPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,14 +178,11 @@ void ffPrintDiskIOHelpFormat(void)
|
|||||||
"Size of data read per second (formatted)",
|
"Size of data read per second (formatted)",
|
||||||
"Size of data written per second (formatted)",
|
"Size of data written per second (formatted)",
|
||||||
"Device name",
|
"Device name",
|
||||||
"Device interconnect type",
|
|
||||||
"Device physical type (SSD / HDD)",
|
|
||||||
"Device raw file path",
|
"Device raw file path",
|
||||||
"Size of data read per second (in bytes)",
|
"Size of data read per second (in bytes)",
|
||||||
"Size of data written per second (in bytes)",
|
"Size of data written per second (in bytes)",
|
||||||
"Number of reads",
|
"Number of reads",
|
||||||
"Number of writes",
|
"Number of writes",
|
||||||
"Device size (formatted)",
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "modules/opencl/opencl.h"
|
#include "modules/opencl/opencl.h"
|
||||||
#include "modules/os/os.h"
|
#include "modules/os/os.h"
|
||||||
#include "modules/packages/packages.h"
|
#include "modules/packages/packages.h"
|
||||||
|
#include "modules/physicaldisk/physicaldisk.h"
|
||||||
#include "modules/player/player.h"
|
#include "modules/player/player.h"
|
||||||
#include "modules/poweradapter/poweradapter.h"
|
#include "modules/poweradapter/poweradapter.h"
|
||||||
#include "modules/processes/processes.h"
|
#include "modules/processes/processes.h"
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "modules/opencl/option.h"
|
#include "modules/opencl/option.h"
|
||||||
#include "modules/os/option.h"
|
#include "modules/os/option.h"
|
||||||
#include "modules/packages/option.h"
|
#include "modules/packages/option.h"
|
||||||
|
#include "modules/physicaldisk/option.h"
|
||||||
#include "modules/player/option.h"
|
#include "modules/player/option.h"
|
||||||
#include "modules/poweradapter/option.h"
|
#include "modules/poweradapter/option.h"
|
||||||
#include "modules/processes/option.h"
|
#include "modules/processes/option.h"
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
|
||||||
|
|
||||||
|
#include "common/option.h"
|
||||||
|
|
||||||
|
typedef struct FFPhysicalDiskOptions
|
||||||
|
{
|
||||||
|
FFModuleBaseInfo moduleInfo;
|
||||||
|
FFModuleArgs moduleArgs;
|
||||||
|
|
||||||
|
FFstrbuf namePrefix;
|
||||||
|
} FFPhysicalDiskOptions;
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
#include "common/printing.h"
|
||||||
|
#include "common/jsonconfig.h"
|
||||||
|
#include "common/parsing.h"
|
||||||
|
#include "detection/physicaldisk/physicaldisk.h"
|
||||||
|
#include "modules/physicaldisk/physicaldisk.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
|
#define FF_PHYSICALDISK_DISPLAY_NAME "Physical Disk"
|
||||||
|
#define FF_PHYSICALDISK_NUM_FORMAT_ARGS 7
|
||||||
|
|
||||||
|
static int sortDevices(const FFPhysicalDiskResult* left, const FFPhysicalDiskResult* right)
|
||||||
|
{
|
||||||
|
return ffStrbufComp(&left->name, &right->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void formatKey(const FFPhysicalDiskOptions* options, FFPhysicalDiskResult* dev, uint32_t index, FFstrbuf* key)
|
||||||
|
{
|
||||||
|
if(options->moduleArgs.key.length == 0)
|
||||||
|
{
|
||||||
|
ffStrbufSetF(key, FF_PHYSICALDISK_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ffStrbufClear(key);
|
||||||
|
ffParseFormatString(key, &options->moduleArgs.key, 2, (FFformatarg[]){
|
||||||
|
{FF_FORMAT_ARG_TYPE_UINT, &index},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
|
||||||
|
const char* error = ffDetectPhysicalDisk(&result, options);
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
ffPrintError(FF_PHYSICALDISK_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffListSort(&result, (const void*) sortDevices);
|
||||||
|
|
||||||
|
uint32_t index = 0;
|
||||||
|
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||||
|
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||||
|
|
||||||
|
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||||
|
{
|
||||||
|
formatKey(options, dev, result.length == 1 ? 0 : index + 1, &key);
|
||||||
|
ffStrbufClear(&buffer);
|
||||||
|
ffParseSize(dev->size, &buffer);
|
||||||
|
|
||||||
|
const char* physicalType = dev->type & FF_PHYSICALDISK_TYPE_HDD
|
||||||
|
? "HDD"
|
||||||
|
: dev->type & FF_PHYSICALDISK_TYPE_SSD
|
||||||
|
? "SSD"
|
||||||
|
: "";
|
||||||
|
const char* removableType = dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE
|
||||||
|
? "Removable"
|
||||||
|
: dev->type & FF_PHYSICALDISK_TYPE_FIXED
|
||||||
|
? "Fixed"
|
||||||
|
: "";
|
||||||
|
|
||||||
|
if(options->moduleArgs.outputFormat.length == 0)
|
||||||
|
{
|
||||||
|
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||||
|
|
||||||
|
if (physicalType[0] || removableType[0])
|
||||||
|
{
|
||||||
|
ffStrbufAppendS(&buffer, " [");
|
||||||
|
if (physicalType[0])
|
||||||
|
ffStrbufAppendS(&buffer, physicalType);
|
||||||
|
if (removableType[0])
|
||||||
|
{
|
||||||
|
if (physicalType[0])
|
||||||
|
ffStrbufAppendS(&buffer, ", ");
|
||||||
|
ffStrbufAppendS(&buffer, removableType);
|
||||||
|
}
|
||||||
|
ffStrbufAppendC(&buffer, ']');
|
||||||
|
}
|
||||||
|
ffStrbufPutTo(&buffer, stdout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ffParseSize(dev->size, &buffer);
|
||||||
|
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_PHYSICALDISK_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial},
|
||||||
|
{FF_FORMAT_ARG_TYPE_STRING, removableType},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||||
|
{
|
||||||
|
ffStrbufDestroy(&dev->name);
|
||||||
|
ffStrbufDestroy(&dev->interconnect);
|
||||||
|
ffStrbufDestroy(&dev->devPath);
|
||||||
|
ffStrbufDestroy(&dev->serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ffParsePhysicalDiskCommandOptions(FFPhysicalDiskOptions* options, const char* key, const char* value)
|
||||||
|
{
|
||||||
|
const char* subKey = ffOptionTestPrefix(key, FF_PHYSICALDISK_MODULE_NAME);
|
||||||
|
if (!subKey) return false;
|
||||||
|
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
|
||||||
|
{
|
||||||
|
ffOptionParseString(key, value, &options->namePrefix);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffParsePhysicalDiskJsonObject(FFPhysicalDiskOptions* options, yyjson_val* module)
|
||||||
|
{
|
||||||
|
yyjson_val *key_, *val;
|
||||||
|
size_t idx, max;
|
||||||
|
yyjson_obj_foreach(module, idx, max, key_, val)
|
||||||
|
{
|
||||||
|
const char* key = yyjson_get_str(key_);
|
||||||
|
if(ffStrEqualsIgnCase(key, "type"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ffStrEqualsIgnCase(key, "namePrefix"))
|
||||||
|
{
|
||||||
|
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffPrintError(FF_PHYSICALDISK_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffGeneratePhysicalDiskJsonConfig(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||||
|
{
|
||||||
|
__attribute__((__cleanup__(ffDestroyPhysicalDiskOptions))) FFPhysicalDiskOptions defaultOptions;
|
||||||
|
ffInitPhysicalDiskOptions(&defaultOptions);
|
||||||
|
|
||||||
|
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
|
||||||
|
|
||||||
|
if (!ffStrbufEqual(&options->namePrefix, &defaultOptions.namePrefix))
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, module, "namePrefix", &options->namePrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffGeneratePhysicalDiskJsonResult(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||||
|
{
|
||||||
|
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
|
||||||
|
const char* error = ffDetectPhysicalDisk(&result, options);
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
yyjson_mut_obj_add_str(doc, module, "error", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||||
|
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||||
|
{
|
||||||
|
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, obj, "interconnect", &dev->interconnect);
|
||||||
|
|
||||||
|
if (dev->type & FF_PHYSICALDISK_TYPE_HDD)
|
||||||
|
yyjson_mut_obj_add_str(doc, obj, "kind", "HDD");
|
||||||
|
else if (dev->type & FF_PHYSICALDISK_TYPE_SSD)
|
||||||
|
yyjson_mut_obj_add_str(doc, obj, "kind", "SSD");
|
||||||
|
else
|
||||||
|
yyjson_mut_obj_add_null(doc, obj, "kind");
|
||||||
|
|
||||||
|
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial);
|
||||||
|
|
||||||
|
if (dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE)
|
||||||
|
yyjson_mut_obj_add_bool(doc, obj, "removable", true);
|
||||||
|
else if (dev->type & FF_PHYSICALDISK_TYPE_FIXED)
|
||||||
|
yyjson_mut_obj_add_bool(doc, obj, "removable", false);
|
||||||
|
else
|
||||||
|
yyjson_mut_obj_add_null(doc, obj, "removable");
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||||
|
{
|
||||||
|
ffStrbufDestroy(&dev->name);
|
||||||
|
ffStrbufDestroy(&dev->interconnect);
|
||||||
|
ffStrbufDestroy(&dev->devPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffPrintPhysicalDiskHelpFormat(void)
|
||||||
|
{
|
||||||
|
ffPrintModuleFormatHelp(FF_PHYSICALDISK_MODULE_NAME, "{1}", FF_PHYSICALDISK_NUM_FORMAT_ARGS, (const char* []) {
|
||||||
|
"Device size (formatted)",
|
||||||
|
"Device name",
|
||||||
|
"Device interconnect type",
|
||||||
|
"Device raw file path",
|
||||||
|
"Serial number",
|
||||||
|
"Device kind (SSD or HDD)",
|
||||||
|
"Device kind (Removable or Fixed)",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
ffOptionInitModuleBaseInfo(
|
||||||
|
&options->moduleInfo,
|
||||||
|
FF_PHYSICALDISK_MODULE_NAME,
|
||||||
|
"Print physical disk information",
|
||||||
|
ffParsePhysicalDiskCommandOptions,
|
||||||
|
ffParsePhysicalDiskJsonObject,
|
||||||
|
ffPrintPhysicalDisk,
|
||||||
|
ffGeneratePhysicalDiskJsonResult,
|
||||||
|
ffPrintPhysicalDiskHelpFormat,
|
||||||
|
ffGeneratePhysicalDiskJsonConfig
|
||||||
|
);
|
||||||
|
ffOptionInitModuleArg(&options->moduleArgs);
|
||||||
|
|
||||||
|
ffStrbufInit(&options->namePrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options)
|
||||||
|
{
|
||||||
|
ffOptionDestroyModuleArg(&options->moduleArgs);
|
||||||
|
ffStrbufDestroy(&options->namePrefix);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fastfetch.h"
|
||||||
|
|
||||||
|
#define FF_PHYSICALDISK_MODULE_NAME "PhysicalDisk"
|
||||||
|
|
||||||
|
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options);
|
||||||
|
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options);
|
||||||
|
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options);
|
||||||
+41
-4
@@ -30,7 +30,24 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va
|
|||||||
else if (ffStrEqualsIgnCase(key, "osFile"))
|
else if (ffStrEqualsIgnCase(key, "osFile"))
|
||||||
ffStrbufSetS(&options->osFile, yyjson_get_str(val));
|
ffStrbufSetS(&options->osFile, yyjson_get_str(val));
|
||||||
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
|
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
|
||||||
options->dsForceDrm = yyjson_get_bool(val);
|
{
|
||||||
|
if (yyjson_is_str(val))
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||||
|
{ "sysfs-only", FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY },
|
||||||
|
{ "false", FF_DS_FORCE_DRM_TYPE_FALSE },
|
||||||
|
{ "true", FF_DS_FORCE_DRM_TYPE_TRUE },
|
||||||
|
{},
|
||||||
|
});
|
||||||
|
if (error)
|
||||||
|
return "Invalid enum value of `dsForceDrm`";
|
||||||
|
else
|
||||||
|
options->dsForceDrm = (FFDsForceDrmType) value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
options->dsForceDrm = yyjson_get_bool(val) ? FF_DS_FORCE_DRM_TYPE_TRUE : FF_DS_FORCE_DRM_TYPE_FALSE;
|
||||||
|
}
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
|
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
|
||||||
options->wmiTimeout = (int32_t) yyjson_get_int(val);
|
options->wmiTimeout = (int32_t) yyjson_get_int(val);
|
||||||
@@ -65,7 +82,14 @@ bool ffOptionsParseGeneralCommandLine(FFOptionsGeneral* options, const char* key
|
|||||||
else if (ffStrEqualsIgnCase(key, "--os-file"))
|
else if (ffStrEqualsIgnCase(key, "--os-file"))
|
||||||
ffOptionParseString(key, value, &options->osFile);
|
ffOptionParseString(key, value, &options->osFile);
|
||||||
else if(ffStrEqualsIgnCase(key, "--ds-force-drm"))
|
else if(ffStrEqualsIgnCase(key, "--ds-force-drm"))
|
||||||
options->dsForceDrm = ffOptionParseBoolean(value);
|
{
|
||||||
|
if (ffOptionParseBoolean(value))
|
||||||
|
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_TRUE;
|
||||||
|
else if (ffStrEqualsIgnCase(value, "sysfs-only"))
|
||||||
|
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY;
|
||||||
|
else
|
||||||
|
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
|
||||||
|
}
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
else if (ffStrEqualsIgnCase(key, "--wmi-timeout"))
|
else if (ffStrEqualsIgnCase(key, "--wmi-timeout"))
|
||||||
options->wmiTimeout = ffOptionParseInt32(key, value);
|
options->wmiTimeout = ffOptionParseInt32(key, value);
|
||||||
@@ -86,7 +110,7 @@ void ffOptionsInitGeneral(FFOptionsGeneral* options)
|
|||||||
options->escapeBedrock = true;
|
options->escapeBedrock = true;
|
||||||
ffStrbufInit(&options->playerName);
|
ffStrbufInit(&options->playerName);
|
||||||
ffStrbufInit(&options->osFile);
|
ffStrbufInit(&options->osFile);
|
||||||
options->dsForceDrm = false;
|
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
options->wmiTimeout = 5000;
|
options->wmiTimeout = 5000;
|
||||||
#endif
|
#endif
|
||||||
@@ -125,7 +149,20 @@ void ffOptionsGenerateGeneralJsonConfig(FFOptionsGeneral* options, yyjson_mut_do
|
|||||||
yyjson_mut_obj_add_strbuf(doc, obj, "osFile", &options->osFile);
|
yyjson_mut_obj_add_strbuf(doc, obj, "osFile", &options->osFile);
|
||||||
|
|
||||||
if (options->dsForceDrm != defaultOptions.dsForceDrm)
|
if (options->dsForceDrm != defaultOptions.dsForceDrm)
|
||||||
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", options->dsForceDrm);
|
{
|
||||||
|
switch (options->dsForceDrm)
|
||||||
|
{
|
||||||
|
case FF_DS_FORCE_DRM_TYPE_FALSE:
|
||||||
|
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", false);
|
||||||
|
break;
|
||||||
|
case FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY:
|
||||||
|
yyjson_mut_obj_add_str(doc, obj, "dsForceDrm", "sysfs-only");
|
||||||
|
break;
|
||||||
|
case FF_DS_FORCE_DRM_TYPE_TRUE:
|
||||||
|
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
#include "util/FFstrbuf.h"
|
#include "util/FFstrbuf.h"
|
||||||
|
|
||||||
|
typedef enum FFDsForceDrmType
|
||||||
|
{
|
||||||
|
FF_DS_FORCE_DRM_TYPE_FALSE = 0, // Disable
|
||||||
|
FF_DS_FORCE_DRM_TYPE_TRUE = 1, // Try `libdrm`, then `sysfs` if libdrm failed
|
||||||
|
FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY, // Use `/sys/class/drm` only
|
||||||
|
} FFDsForceDrmType;
|
||||||
|
|
||||||
typedef struct FFOptionsGeneral
|
typedef struct FFOptionsGeneral
|
||||||
{
|
{
|
||||||
bool multithreading;
|
bool multithreading;
|
||||||
@@ -12,7 +19,7 @@ typedef struct FFOptionsGeneral
|
|||||||
FFstrbuf playerName;
|
FFstrbuf playerName;
|
||||||
FFstrbuf osFile;
|
FFstrbuf osFile;
|
||||||
bool escapeBedrock;
|
bool escapeBedrock;
|
||||||
bool dsForceDrm;
|
FFDsForceDrmType dsForceDrm;
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
int32_t wmiTimeout;
|
int32_t wmiTimeout;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
|
|||||||
ffInitOpenCLOptions(&options->openCL);
|
ffInitOpenCLOptions(&options->openCL);
|
||||||
ffInitOpenGLOptions(&options->openGL);
|
ffInitOpenGLOptions(&options->openGL);
|
||||||
ffInitPackagesOptions(&options->packages);
|
ffInitPackagesOptions(&options->packages);
|
||||||
|
ffInitPhysicalDiskOptions(&options->physicalDisk);
|
||||||
ffInitPlayerOptions(&options->player);
|
ffInitPlayerOptions(&options->player);
|
||||||
ffInitPowerAdapterOptions(&options->powerAdapter);
|
ffInitPowerAdapterOptions(&options->powerAdapter);
|
||||||
ffInitProcessesOptions(&options->processes);
|
ffInitProcessesOptions(&options->processes);
|
||||||
@@ -98,6 +99,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
|
|||||||
ffDestroyOSOptions(&options->os);
|
ffDestroyOSOptions(&options->os);
|
||||||
ffDestroyOpenCLOptions(&options->openCL);
|
ffDestroyOpenCLOptions(&options->openCL);
|
||||||
ffDestroyOpenGLOptions(&options->openGL);
|
ffDestroyOpenGLOptions(&options->openGL);
|
||||||
|
ffDestroyPhysicalDiskOptions(&options->physicalDisk);
|
||||||
ffDestroyPackagesOptions(&options->packages);
|
ffDestroyPackagesOptions(&options->packages);
|
||||||
ffDestroyPlayerOptions(&options->player);
|
ffDestroyPlayerOptions(&options->player);
|
||||||
ffDestroyPowerAdapterOptions(&options->powerAdapter);
|
ffDestroyPowerAdapterOptions(&options->powerAdapter);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ typedef struct FFOptionsModules
|
|||||||
FFOpenCLOptions openCL;
|
FFOpenCLOptions openCL;
|
||||||
FFOpenGLOptions openGL;
|
FFOpenGLOptions openGL;
|
||||||
FFPackagesOptions packages;
|
FFPackagesOptions packages;
|
||||||
|
FFPhysicalDiskOptions physicalDisk;
|
||||||
FFPlayerOptions player;
|
FFPlayerOptions player;
|
||||||
FFPowerAdapterOptions powerAdapter;
|
FFPowerAdapterOptions powerAdapter;
|
||||||
FFProcessesOptions processes;
|
FFProcessesOptions processes;
|
||||||
|
|||||||
+5
-3
@@ -59,9 +59,9 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
|
|||||||
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
||||||
if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
|
if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t newCap = strbuf->allocated + (free - oldFree);
|
uint32_t newCap = strbuf->allocated + (free - oldFree);
|
||||||
|
|
||||||
if(strbuf->allocated == 0)
|
if(strbuf->allocated == 0)
|
||||||
{
|
{
|
||||||
newCap += strbuf->length + 1; // +1 for the NUL
|
newCap += strbuf->length + 1; // +1 for the NUL
|
||||||
@@ -74,7 +74,7 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
||||||
|
|
||||||
strbuf->allocated = newCap;
|
strbuf->allocated = newCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +99,8 @@ void ffStrbufAppendC(FFstrbuf* strbuf, char c)
|
|||||||
|
|
||||||
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c)
|
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c)
|
||||||
{
|
{
|
||||||
|
if (num == 0) return;
|
||||||
|
|
||||||
ffStrbufEnsureFree(strbuf, num);
|
ffStrbufEnsureFree(strbuf, num);
|
||||||
memset(&strbuf->chars[strbuf->length], c, num);
|
memset(&strbuf->chars[strbuf->length], c, num);
|
||||||
strbuf->length += num;
|
strbuf->length += num;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ static void getExePath(FFPlatform* platform)
|
|||||||
FFstrbuf* const exePath = &platform->exePath;
|
FFstrbuf* const exePath = &platform->exePath;
|
||||||
ffStrbufEnsureFree(exePath, PATH_MAX);
|
ffStrbufEnsureFree(exePath, PATH_MAX);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated);
|
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated - 1);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
int exePathLen = proc_pidpath((int) getpid(), exePath->chars, exePath->allocated);
|
int exePathLen = proc_pidpath((int) getpid(), exePath->chars, exePath->allocated);
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ bool ffIsSmbiosValueSet(FFstrbuf* value)
|
|||||||
!ffStrbufIgnCaseEqualS(value, "Undefined") &&
|
!ffStrbufIgnCaseEqualS(value, "Undefined") &&
|
||||||
!ffStrbufIgnCaseEqualS(value, "Not Specified") &&
|
!ffStrbufIgnCaseEqualS(value, "Not Specified") &&
|
||||||
!ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
|
!ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
|
||||||
|
!ffStrbufIgnCaseEqualS(value, "Not Defined") &&
|
||||||
|
!ffStrbufIgnCaseEqualS(value, "Not Available") &&
|
||||||
!ffStrbufIgnCaseEqualS(value, "INVALID") &&
|
!ffStrbufIgnCaseEqualS(value, "INVALID") &&
|
||||||
!ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
|
!ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
|
||||||
!ffStrbufIgnCaseEqualS(value, "All Series") &&
|
!ffStrbufIgnCaseEqualS(value, "All Series") &&
|
||||||
|
|||||||
Reference in New Issue
Block a user