mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
254 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 48fc598ccb | |||
| 3a8138e3da | |||
| 4251456619 | |||
| 5bc6d16138 | |||
| 11374e73ae | |||
| 373cb4106a | |||
| a0949c5675 | |||
| 97b1eb155f | |||
| 093cc6fba2 | |||
| c8a3ae9186 | |||
| 778013aec9 | |||
| e6af1bfb91 | |||
| 9d8a83349c | |||
| 3bc6be9139 | |||
| 1eef6f837b | |||
| 85ed4b136f | |||
| 339e08fef1 | |||
| 5957831f3f | |||
| 016b1e6961 | |||
| 486ade0e71 | |||
| e021cfe77a | |||
| a016397961 | |||
| 99e8d1f2bb | |||
| 263d2902dd | |||
| 292fa0686f | |||
| f2755a844b | |||
| 1d21d02878 | |||
| b3062499f4 | |||
| 49bb957c86 | |||
| 8f27e43929 | |||
| 8774fb3fb7 | |||
| 356501270a | |||
| 5a04a2ecc3 | |||
| edcd7995e5 | |||
| 7f212025de | |||
| 63cc8e5523 | |||
| c3023259e2 | |||
| 994a8b4dd0 | |||
| 76710c8159 | |||
| 70820e424b | |||
| 9221e2b41d | |||
| 71a2e55869 | |||
| dc5ff01e74 | |||
| fc8ddce182 | |||
| dd67010e5c | |||
| d1ba690973 | |||
| 01f400c15f | |||
| 33c905aa99 | |||
| fe7c4f724e | |||
| abadcb95bd | |||
| 3d8050fd5c | |||
| 4d842ac6b6 | |||
| b76e62685e | |||
| 1279bbcf28 | |||
| 4e9fecc767 | |||
| 1c4953a467 | |||
| 3ad5d5c8b0 | |||
| 865929b173 | |||
| 9324136f52 | |||
| f601d2d9f5 | |||
| 54de7c8c96 | |||
| 3bb3bd542e | |||
| e6e7572bc2 | |||
| 884d256a34 | |||
| ed8430fb2f | |||
| 7fc1f0098e | |||
| 3839ee60d6 | |||
| 6f266a1609 | |||
| 026489c934 | |||
| 1d03747ec3 | |||
| a2919f5b2e | |||
| 680978b0d3 | |||
| af813dee00 | |||
| c281c46fff | |||
| 1f5e56c69e | |||
| 35d431dd3f | |||
| 6a2e8de563 | |||
| 9528cf96f0 | |||
| 66deb4316b | |||
| 61e9db97b9 | |||
| 66fbda9542 | |||
| 5137a9e7a4 | |||
| f76981c241 | |||
| 85050f7ff1 | |||
| 0b39d6fc59 | |||
| b7dd7fea0a | |||
| cc51596e5c | |||
| b566ffe81b | |||
| 60c06a888c | |||
| 8ceda02bbb | |||
| c005bc50c2 | |||
| 52411f6e37 | |||
| 31f620c041 | |||
| fdbd8d9ad5 | |||
| 1cad1dfdb0 | |||
| 4a1037d2b6 | |||
| dbcd5b922a | |||
| 8982b860f9 | |||
| 373b4353bb | |||
| ace336dfa9 | |||
| 4060626382 | |||
| 9f9e3dd931 | |||
| 3ed5a250a4 | |||
| fc969b01c7 | |||
| 41e22ea866 | |||
| 0b4a6055c6 | |||
| b340d4e149 | |||
| 878e516880 | |||
| 4e3673a2bb | |||
| 10c8c1b4bf | |||
| 17e3853f38 | |||
| 1bc41dfa54 | |||
| 8c227ae4b8 | |||
| c5c2589f4d | |||
| b273693842 | |||
| 52de8df1f9 | |||
| be99c4ca6e | |||
| 8133c3365f | |||
| 6226ccc70e | |||
| 88917cb14f | |||
| a93e2aafdb | |||
| 5848b5fc24 | |||
| 934b6291e3 | |||
| 90068ab474 | |||
| 5567e6cc5e | |||
| 8b3017c0d9 | |||
| f9f15ba844 | |||
| b282ac5d47 | |||
| 6577884417 | |||
| c4ee606955 | |||
| 59c80820f2 | |||
| c11e14f7e1 | |||
| ab6a770155 | |||
| 0e99486efe | |||
| f82f3002e4 | |||
| 0bed182784 | |||
| d39be955b1 | |||
| 3b2790cccc | |||
| 3ea0406b69 | |||
| 6429c20466 | |||
| 88ebeb21e2 | |||
| f28f5e2874 | |||
| 637c37e81c | |||
| b2c779dea9 | |||
| 89d636447b | |||
| 3dc51d5f88 | |||
| 60ff89c794 | |||
| f973572c5a | |||
| ea78665971 | |||
| 80b48dd2d1 | |||
| df6eed7a02 | |||
| c9ac09f9eb | |||
| 67597e4566 | |||
| 611de77980 | |||
| 0fde835629 | |||
| f373e07847 | |||
| 89e4403cc8 | |||
| c68d21e215 | |||
| f14cd2c6e8 | |||
| d58d786c83 | |||
| 9f37557177 | |||
| aa63c4f5f2 | |||
| a378d2ad62 | |||
| 2ab2dd4d48 | |||
| 2a83b86ba4 | |||
| d967d05019 | |||
| 9ef8580d93 | |||
| 813b80c5a8 | |||
| ddce9b2357 | |||
| 9342d74c93 | |||
| d6028370e7 | |||
| e425d7df63 | |||
| a4a2ae7d67 | |||
| 99aa0638cc | |||
| 1a9e637134 | |||
| f322405c04 | |||
| e4202635af | |||
| 2f13ee3814 | |||
| 2bfde87f84 | |||
| f38a51c9bc | |||
| 28ec935c42 | |||
| d939f95c69 | |||
| e0fd5111fe | |||
| 4736031538 | |||
| 66085c087e | |||
| e0253d71c0 | |||
| dadd4bfab6 | |||
| 2f3861e732 | |||
| 851f271ed5 | |||
| d3e40f625b | |||
| 7c1991c2e3 | |||
| b8048ee488 | |||
| b99f54b9f4 | |||
| b38d7a4919 | |||
| 45f7e2c0b2 | |||
| 5a8dda27ff | |||
| 1ea3264b13 | |||
| 852a729581 | |||
| 0f454b7140 | |||
| 9c47a3a9e7 | |||
| 4adf7fda28 | |||
| e2fc83fd48 | |||
| dd41dfa000 | |||
| 14d6157901 | |||
| 74586a9df1 | |||
| c5d4b20729 | |||
| b152b383a2 | |||
| ae26692ef6 | |||
| 4f807f26a9 | |||
| 4bef801337 | |||
| 41240e9460 | |||
| 3bb82423b3 | |||
| b87df82d58 | |||
| c145ce49a5 | |||
| 8c4fb5d6d4 | |||
| eae0fee032 | |||
| 4472a13f41 | |||
| 5b001d6bd6 | |||
| 1b52029fce | |||
| 2176ea2937 | |||
| ac2266c72f | |||
| 0dc40a2632 | |||
| ca975f8e81 | |||
| c4c6fe6668 | |||
| 0a00f5721e | |||
| 69f180beea | |||
| 0e9cdf75b5 | |||
| 7d7e219c0a | |||
| 4937ccfa81 | |||
| d0d29c163b | |||
| 901e0eb177 | |||
| 87446e6eef | |||
| bfaa73a2c7 | |||
| 373e288d03 | |||
| 82170ceab0 | |||
| 009a7888b5 | |||
| ab1a11c9fa | |||
| 68746275f8 | |||
| 491cfb94b6 | |||
| 79c8919431 | |||
| e98afa8315 | |||
| 86783c033b | |||
| f01944de41 | |||
| ebfdeef25c | |||
| 9a36d63d18 | |||
| e45ff546ed | |||
| 2700390371 | |||
| 5c01685d69 | |||
| d897472572 | |||
| 8410a66277 | |||
| 856d229b36 | |||
| b33692aa7d | |||
| e90c5cb241 | |||
| 03cd283755 |
@@ -1,80 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: '[BUG] '
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Be sure to read the [FAQ](https://github.com/fastfetch-cli/fastfetch?tab=readme-ov-file#faq) before submitting a new issue.
|
||||
|
||||
<!-- We will try hard to solve the issue. However since platforms and hardwares vary greatly, it can be hard to find the root cause of an issue. Providing the following information may help us greatly. Thanks in advance! -->
|
||||
|
||||
# General description of bug:
|
||||
|
||||
* What happened:
|
||||
* What should happen:
|
||||
* Fastfetch version used: <!-- please use the latest version, if possible -->
|
||||
* Did it work in an older version: <!-- if yes, which version -->
|
||||
* Where did you get the binary: <!-- GitHub release / GitHub Actions / installed with a package manager (please tell us which package manager you used!) / built from source yourself -->
|
||||
* Does this issue still occur in [the latest dev build](https://github.com/fastfetch-cli/fastfetch/actions/)?
|
||||
|
||||
# Often helpful information:
|
||||
|
||||
Screenshot:
|
||||
<!-- Paste the screenshot here -->
|
||||
|
||||
The content of the configuration file you use (if any):
|
||||
```
|
||||
// Paste here
|
||||
```
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
```
|
||||
// Paste here
|
||||
```
|
||||
|
||||
Output of `fastfetch --list-features`:
|
||||
```
|
||||
// Paste here
|
||||
```
|
||||
|
||||
## If fastfatch crashed or froze
|
||||
|
||||
Paste the stacktrace here. You may get it with:
|
||||
|
||||
```shell
|
||||
# You may need Ctrl+C to stop the process if it freezes
|
||||
gdb -q -ex 'set confirm off' -ex run -ex 'bt full' -ex quit --args /path/to/fastfetch
|
||||
```
|
||||
|
||||
If you are able to identify which module crashed, the strace can be helpful too
|
||||
|
||||
```shell
|
||||
strace /path/to/fastfetch --multithreading false -s {MODULE} --pipe
|
||||
```
|
||||
|
||||
If you cannot do the instructions above, please upload the core dump file:
|
||||
|
||||
## If fastfetch is slow
|
||||
|
||||
Use `time fastfetch --stat` to show time usage for each module.
|
||||
|
||||
## If an image or logo didn't show
|
||||
|
||||
<!-- Please make sure your terminal supports the image protocol you used. Note that GNOME Terminal doesn't support any image protocols. -->
|
||||
|
||||
* The image protocol you used:
|
||||
* The terminal you used:
|
||||
* Upload the image file here, or paste the image URL:
|
||||
* Does it work with `--logo-width {WIDTH} --logo-height {HEIGHT}`?
|
||||
|
||||
## If fastfetch behaves incorrectly on shell startup
|
||||
|
||||
* The bug is reproducible with a clean shell configuration (i.e. `fastfetch` is the only line in `.zshrc` or `~/.config/fish/config.fish`):
|
||||
* Does `sleep 1` before running `fastfetch` work?
|
||||
@@ -0,0 +1,113 @@
|
||||
name: Crash Bug Report
|
||||
description: If fastfetch crashes or freezes
|
||||
title: "[BUG] "
|
||||
labels: ["bug", "crash", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report! We will try hard to solve the issue.
|
||||
However since platforms and hardwares vary greatly, it can be hard to find the root cause of an issue.
|
||||
Providing the following information may help us greatly. Thanks in advance!
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Read the FAQ first
|
||||
description: Please check if the issue is already covered in the FAQ.
|
||||
options:
|
||||
- label: I have checked the FAQ but the issue is not covered
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "### General description of the bug"
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of what the bug is.
|
||||
placeholder: I was trying to [...] but [...]
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Version used
|
||||
description: Fastfetch version used. Please use the latest version (found in the [releases](https://github.com/fastfetch-cli/fastfetch/releases)) if possible.
|
||||
placeholder: Result of `fastfetch --version`
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Bug prevalence
|
||||
description: How often does the bug occur?
|
||||
options:
|
||||
-
|
||||
- Always
|
||||
- Sometimes
|
||||
- Rarely
|
||||
- Once
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Regression
|
||||
description: Did it work in an older version?
|
||||
options:
|
||||
-
|
||||
- Not sure
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Installation
|
||||
description: Where did you install fastfetch from?
|
||||
options:
|
||||
-
|
||||
- GitHub Releases
|
||||
- GitHub Actions (nightly)
|
||||
- Built from source
|
||||
- Package manager
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Package manager
|
||||
description: Which package manager did you use if applicable?
|
||||
placeholder: e.g. `apt`, `pacman`, `brew`, `scoop`
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: '### Often helpful information'
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Configuration
|
||||
description: If applicable, paste your configuration file here.
|
||||
placeholder: cat ~/.config/fastfetch/config.jsonc
|
||||
render: jsonc
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Paste the stacktrace here. You may get it with:
|
||||
|
||||
```shell
|
||||
# You may need Ctrl+C to stop the process if it freezes
|
||||
gdb -q -ex 'set confirm off' -ex run -ex 'bt full' -ex quit --args /path/to/fastfetch
|
||||
```
|
||||
|
||||
If you are able to identify which module crashed, the strace can be helpful too
|
||||
|
||||
```shell
|
||||
strace /path/to/fastfetch --multithreading false -s {MODULE} --pipe
|
||||
```
|
||||
|
||||
If you cannot do the instructions above, please upload the core dump file if available.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Stacktrace
|
||||
description: Paste the stacktrace or core dump file here.
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,106 @@
|
||||
name: General Bug Report
|
||||
description: If something is not working as expected (wrong output, missing info, etc)
|
||||
title: "[BUG] "
|
||||
labels: ["bug", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report! We will try hard to solve the issue.
|
||||
However since platforms and hardwares vary greatly, it can be hard to find the root cause of an issue.
|
||||
Providing the following information may help us greatly. Thanks in advance!
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Read the FAQ first
|
||||
description: Please check if the issue is already covered in the FAQ.
|
||||
options:
|
||||
- label: I have checked the FAQ but the issue is not covered
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "### General description of the bug"
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of what the bug is.
|
||||
placeholder: I was trying to [...] but [...]
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Version used
|
||||
description: Fastfetch version used. Please use the latest version (found in the [releases](https://github.com/fastfetch-cli/fastfetch/releases)) if possible.
|
||||
placeholder: Result of `fastfetch --version`
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Bug prevalence
|
||||
description: How often does the bug occur?
|
||||
options:
|
||||
-
|
||||
- Always
|
||||
- Sometimes
|
||||
- Rarely
|
||||
- Once
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Regression
|
||||
description: Did it work in an older version?
|
||||
options:
|
||||
-
|
||||
- Not sure
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Installation
|
||||
description: Where did you install fastfetch from?
|
||||
options:
|
||||
-
|
||||
- GitHub Releases
|
||||
- GitHub Actions (nightly)
|
||||
- Built from source
|
||||
- Package manager
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Package manager
|
||||
description: Which package manager did you use if applicable?
|
||||
placeholder: e.g. `apt`, `pacman`, `brew`, `scoop`
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: '### Often helpful information'
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Configuration
|
||||
description: If applicable, paste your configuration file here.
|
||||
placeholder: cat ~/.config/fastfetch/config.jsonc
|
||||
render: jsonc
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: System information
|
||||
description: Output of `fastfetch -c all.jsonc --stat --format json`
|
||||
placeholder: |
|
||||
Note that this output will contain you public IP.
|
||||
If it is not relevant for the issue, feel free to remove it before uploading.
|
||||
render: jsonc
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Features built-in
|
||||
description: Output of `fastfetch --list-features`
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,129 @@
|
||||
name: Logo Bug Report
|
||||
description: If my image logo is not displayed correctly
|
||||
title: "[BUG] "
|
||||
labels: ["bug", "logo", "triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report! We will try hard to solve the issue.
|
||||
However since platforms and hardwares vary greatly, it can be hard to find the root cause of an issue.
|
||||
Providing the following information may help us greatly. Thanks in advance!
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Read the FAQ first
|
||||
description: Please check if the issue is already covered in the FAQ.
|
||||
options:
|
||||
- label: I have checked the FAQ but the issue is not covered
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "### General description of the bug"
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of what the bug is.
|
||||
placeholder: I was trying to [...] but [...]
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Version used
|
||||
description: Fastfetch version used. Please use the latest version (found in the [releases](https://github.com/fastfetch-cli/fastfetch/releases)) if possible.
|
||||
placeholder: Result of `fastfetch --version`
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Bug prevalence
|
||||
description: How often does the bug occur?
|
||||
options:
|
||||
-
|
||||
- Always
|
||||
- Sometimes
|
||||
- Rarely
|
||||
- Once
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Regression
|
||||
description: Did it work in an older version?
|
||||
options:
|
||||
-
|
||||
- Not sure
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Installation
|
||||
description: Where did you install fastfetch from?
|
||||
options:
|
||||
-
|
||||
- GitHub Releases
|
||||
- GitHub Actions (nightly)
|
||||
- Built from source
|
||||
- Package manager
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Package manager
|
||||
description: Which package manager did you use if applicable?
|
||||
placeholder: e.g. `apt`, `pacman`, `brew`, `scoop`
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: '### Often helpful information'
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Configuration
|
||||
description: If applicable, paste your configuration file here.
|
||||
placeholder: cat ~/.config/fastfetch/config.jsonc
|
||||
render: jsonc
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
#### If an image or logo didn't show
|
||||
|
||||
Please make sure your terminal supports the image protocol you used.
|
||||
Note that GNOME Terminal doesn't support any image protocols as of now
|
||||
|
||||
Some tips:
|
||||
1. Try `fastfetch --show-errors` to see if there are any errors.
|
||||
2. Try `fastfetch --logo-width {WIDTH} --logo-height {HEIGHT}`. Some protocols may require a image size being set.
|
||||
- type: input
|
||||
attributes:
|
||||
label: Image protocol
|
||||
description: The image protocol you used
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Terminal
|
||||
description: The terminal you used
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Image tried
|
||||
description: Upload the image file, or paste the image URL here
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Error message
|
||||
description: Error message printed by `fastfetch -s none --show-errors`, if any
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Features built-in
|
||||
description: Output of `fastfetch --list-features`
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: '[FEAT] '
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Be sure to read [FAQ](https://github.com/fastfetch-cli/fastfetch?tab=readme-ov-file#faq) before submitting a new issue.
|
||||
|
||||
## Wanted features:
|
||||
|
||||
<!-- Your features here -->
|
||||
|
||||
## Motivation:
|
||||
|
||||
<!-- Your motivation here -->
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for this project
|
||||
title: "[FEAT] "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Fastfetch is a system information tool. We only accept hardware or system level software feature requests.
|
||||
For most personal uses, I recommend using `Command` module to detect it yourself, which can be used to grab output from a custom shell script:
|
||||
|
||||
```jsonc
|
||||
// This module shows the git version
|
||||
{
|
||||
"modules": [
|
||||
{
|
||||
"type": "command",
|
||||
"key": "Git",
|
||||
"text": "git version",
|
||||
"format": "{~12}" // cut the first 12 characters
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of what the feature is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: Why do you want this feature? Why doesn't `Command` module suffice for you?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
name: Logo request
|
||||
about: Request a new logo
|
||||
title: '[LOGO] '
|
||||
labels: logo request
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Tip: A logo can be displayed by fastfetch without getting into fastfetch's official repo. For highly customized logo for personal use, it's recommended to keep it locally. Please refer to https://github.com/fastfetch-cli/fastfetch/wiki/Migrate-Neofetch-Logo-To-Fastfetch
|
||||
|
||||
# OS
|
||||
```
|
||||
Paste content of /etc/os-release and /etc/lsb-release here. If none of these files exist, describe a way to identify the distro
|
||||
```
|
||||
|
||||
# Ascii
|
||||
|
||||
An ASCII logo should not take up too much space (smaller than 50x20 characters). Please also include the color codes if not available in `os-release`
|
||||
|
||||
```
|
||||
Paste ascii art here.
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Logo Request
|
||||
description: Request a new ASCII logo for your favorite distro
|
||||
title: "[LOGO] "
|
||||
labels: ["logo request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Tip: A logo can be displayed by fastfetch without getting into fastfetch's official repo.
|
||||
For highly customized logo for personal use, it's recommended to keep it locally.
|
||||
Please refer to https://github.com/fastfetch-cli/fastfetch/wiki/Migrate-Neofetch-Logo-To-Fastfetch
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: OS
|
||||
description: Paste content of `/etc/os-release` and `/etc/lsb-release` here. If none of these files exist, describe a way to identify the distro
|
||||
placeholder: cat /etc/os-release
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: ASCII Art
|
||||
description: An ASCII logo should not take up too much space (smaller than 50x20 characters). Please also include the color codes if not available in `os-release`
|
||||
placeholder: Paste ASCII art here
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Original Image
|
||||
description: If the ASCII art is based on an image, please provide a link to the original image
|
||||
placeholder: Image URL or distro website URL
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: The ASCII art is smaller than 50x20 characters (width x height)
|
||||
required: true
|
||||
- label: The ASCII art contains color codes, or the color codes are available in `os-release`
|
||||
required: true
|
||||
+175
-39
@@ -56,7 +56,7 @@ jobs:
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
run: ctest --output-on-failure
|
||||
|
||||
linux-amd64:
|
||||
name: Linux-amd64
|
||||
@@ -73,6 +73,12 @@ jobs:
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- name: cat /etc/os-release
|
||||
run: cat /etc/os-release
|
||||
|
||||
- name: cat /proc/cpuinfo
|
||||
run: cat /proc/cpuinfo
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev python3-requests
|
||||
|
||||
@@ -111,7 +117,7 @@ jobs:
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
run: ctest --output-on-failure
|
||||
|
||||
- name: get fastfetch version
|
||||
id: ffversion
|
||||
@@ -125,7 +131,7 @@ jobs:
|
||||
|
||||
linux-aarch64:
|
||||
name: Linux-aarch64
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-22.04-arm
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
@@ -133,24 +139,45 @@ jobs:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: uraimo/run-on-arch-action@v2
|
||||
id: runcmd
|
||||
with:
|
||||
arch: aarch64
|
||||
distro: ubuntu20.04
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- name: cat /etc/os-release
|
||||
run: cat /etc/os-release
|
||||
|
||||
- name: cat /proc/cpuinfo
|
||||
run: cat /proc/cpuinfo
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev python3-requests libchafa-dev libddcutil-dev rpm
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package --verbose -j4
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: print dependencies
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest --output-on-failure
|
||||
|
||||
- name: get fastfetch version
|
||||
id: ffversion
|
||||
run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -158,8 +185,8 @@ jobs:
|
||||
name: fastfetch-linux-aarch64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-armv7:
|
||||
name: Linux-armv7
|
||||
linux-armv7l:
|
||||
name: Linux-armv7l
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
@@ -189,12 +216,48 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-armv7
|
||||
name: fastfetch-linux-armv7l
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-armv6l:
|
||||
name: Linux-armv6l
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: uraimo/run-on-arch-action@v2
|
||||
id: runcmd
|
||||
with:
|
||||
arch: armv6
|
||||
distro: bookworm
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y wget
|
||||
apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-armv6l
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-riscv64:
|
||||
@@ -224,7 +287,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -232,6 +295,76 @@ jobs:
|
||||
name: fastfetch-linux-riscv64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-ppc64le:
|
||||
name: Linux-ppc64le
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: uraimo/run-on-arch-action@v2
|
||||
id: runcmd
|
||||
with:
|
||||
arch: ppc64le
|
||||
distro: ubuntu20.04
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-ppc64le
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-s390x:
|
||||
name: Linux-s390x
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: uraimo/run-on-arch-action@v2
|
||||
id: runcmd
|
||||
with:
|
||||
arch: s390x
|
||||
distro: ubuntu20.04
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-s390x
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
musl-amd64:
|
||||
name: Musl-amd64
|
||||
runs-on: ubuntu-latest
|
||||
@@ -263,7 +396,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
shell: alpine.sh {0}
|
||||
|
||||
- name: upload artifacts
|
||||
@@ -319,7 +452,7 @@ jobs:
|
||||
run: otool -L fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
run: ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -351,7 +484,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
cpack
|
||||
|
||||
- name: upload artifacts
|
||||
@@ -377,7 +510,7 @@ jobs:
|
||||
architecture: x86-64
|
||||
cpu_count: 4
|
||||
shell: bash
|
||||
version: '14.1'
|
||||
version: '14.2'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
@@ -389,7 +522,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -424,7 +557,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -449,10 +582,10 @@ jobs:
|
||||
architecture: x86-64
|
||||
cpu_count: 4
|
||||
shell: bash
|
||||
version: '7.5'
|
||||
version: '7.6'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio py3-requests
|
||||
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio hwdata py3-requests
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -460,7 +593,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -485,7 +618,7 @@ jobs:
|
||||
architecture: x86-64
|
||||
cpu_count: 4
|
||||
shell: bash
|
||||
version: '10.0'
|
||||
version: '10.1'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick pulseaudio opencl-headers ocl-icd py312-requests
|
||||
@@ -496,7 +629,7 @@ jobs:
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -555,7 +688,7 @@ jobs:
|
||||
run: ldd fastfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
run: ctest --output-on-failure
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
@@ -576,8 +709,11 @@ jobs:
|
||||
needs:
|
||||
- linux-amd64
|
||||
- linux-aarch64
|
||||
- linux-armv7
|
||||
- linux-armv7l
|
||||
- linux-armv6l
|
||||
- linux-riscv64
|
||||
- linux-ppc64le
|
||||
- linux-s390x
|
||||
- musl-amd64
|
||||
- macos-universal
|
||||
- freebsd-amd64
|
||||
|
||||
+202
@@ -1,3 +1,205 @@
|
||||
# 2.36.1
|
||||
|
||||
Changes:
|
||||
* To use [the native arm64 runner of Github Action](https://github.blog/changelog/2025-01-16-linux-arm64-hosted-runners-now-available-for-free-in-public-repositories-public-preview/), Linux aarch64 binary is built with Ubuntu 22.04 (Glibc 2.35, Debian 12).
|
||||
|
||||
Bugfixes:
|
||||
* Chimera Linux logo is now displayed correctly (#1554, Logo)
|
||||
* Regression of 2.36.0
|
||||
* Fix building on Haiku
|
||||
|
||||
Logo:
|
||||
* Fix ALT Linux
|
||||
|
||||
# 2.36.0
|
||||
|
||||
Bugfixes:
|
||||
* Trim leading slash for login shells (Shell, OpenBSD)
|
||||
* Prefer SOC name if available over CPU name (CPU, Linux)
|
||||
|
||||
Features:
|
||||
* Use kernel API to detect sound devices (Sound, NetBSD)
|
||||
* Use sndio for sound server detection on OpenBSD (Sound, OpenBSD)
|
||||
* Add minimal implementation for Haiku (#1538, Haiku)
|
||||
* Support CPU & GPU temperature detection for M4x (CPU / GPU, macOS)
|
||||
* Support VMEM size detection for old Nvidia cards (GPU, Linux)
|
||||
* Use [recommendedMaxWorkingSetSize](https://developer.apple.com/documentation/metal/mtldevice/recommendedmaxworkingsetsize) as total GPU mem size (GPU, macOS)
|
||||
* Support Physical core count and CPU package count detection for loongarch (CPU, Linux)
|
||||
* Split ID_LIKE when used for distro matching (#1540, Logo)
|
||||
* Capitalize `{type}`'s first letter in custom format (#1543, Display)
|
||||
* Support model name detection for s390x (CPU, Linux)
|
||||
* Support more Armbian variants detection (#1547, OS, Linux)
|
||||
* Support the syntax of `{$ENV_VAR}` in custom format, which will be replaced by the value of the environment variable `ENV_VAR` (#1541)
|
||||
* This is another way to pass 3rd-party data to fastfetch besides `Custom` module.
|
||||
* Improve performance of Tilix version detection (Terminal, Linux)
|
||||
|
||||
Logo:
|
||||
* Update arch_old
|
||||
* Add Nexa Linux
|
||||
* Add filotimo
|
||||
* Update some distro names
|
||||
|
||||
# 2.35.0
|
||||
|
||||
Bugfixes:
|
||||
* Suppress output of EGL again (#1513, GPU, Linux)
|
||||
* Regression of 2.34.0
|
||||
|
||||
Features:
|
||||
* Show SOC name reported in `cpuinfo` if available (#1510, CPU, Linux)
|
||||
* Change package manager name of NetBSD from `pkg` to `pkgsrc` (#1515, Packages, NetBSD)
|
||||
* Detect SOC name on RISCV (#1519, CPU, Linux)
|
||||
* Report marketing name of new QS8Es (CPU, Android)
|
||||
* Acquire acquire more os info from lsb-release if missing from os-release (#1521)
|
||||
* CMake: add option `-DCUSTOM_LSB_RELEASE_PATH` to specify the path of `lsb-release` file
|
||||
* `-DCUSTOM_OS_RELEASE_PATH` has been supported since `v2.11.4`
|
||||
* Report more SOC names on Android (CPU, Android)
|
||||
* Support duration printing in custom format (Disk / Users)
|
||||
* For example:
|
||||
```jsonc
|
||||
{
|
||||
"modules": [
|
||||
{
|
||||
"key": "OS Installation Date", // No longer need to write bash scripts
|
||||
"type": "disk",
|
||||
"folders": "/", // Different OSes may need to specify different folders
|
||||
"format": "{create-time:10} [{days} days]" // Reports the creation date of the root folder
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Logo:
|
||||
* Add Arch_old
|
||||
* Update key color of NetBSD_small
|
||||
* Fix OpenBSD and many other ascii logos (#1522)
|
||||
|
||||
# 2.34.1
|
||||
|
||||
An early release to fix KDE Plasma 6.3 compatibility. Hopefully it can be accepted by package managers before KDE 6.3 is officially released.
|
||||
|
||||
To package managers: if you find fastfetch bugs, it's highly appreciated if you can report them to the upstream, so that all users can benefit from the fix, instead of maintaining out-of-tree patches. Thanks!
|
||||
|
||||
Features:
|
||||
* Report vendor name when detecting GPUs by OpenGL
|
||||
* Note: the vendor name is actually the creator of the OpenGL driver (such as `Mesa`) and may not be the same as the GPU vendor.
|
||||
|
||||
Bugfixes:
|
||||
* Fix Ghostty termfont detection (#1495, TerminalFont, macOS)
|
||||
* Fix compatibility with KDE Plasma 6.3 (#1504, Display, Linux)
|
||||
* Make memory usage detection logic consistent with other systems (Memory, OpenBSD / NetBSD)
|
||||
* Report media file name if media title is not available (Media)
|
||||
* Fix max frequency detection for CPUs with both performance and efficiency cores (CPU, FreeBSD)
|
||||
|
||||
Logo:
|
||||
* Add HeliumOS
|
||||
* Add Oreon
|
||||
* Update SnigdhaOS
|
||||
|
||||
# 2.34.0
|
||||
|
||||
Changes:
|
||||
* We now print distro pretty name if available (OS)
|
||||
* This is a long requested feature. However, it may break some distros. File a bug with the content of `/etc/os-release` if it breaks your distro.
|
||||
|
||||
Bugfixes:
|
||||
* Fix thunderbolt version of new MBPs (#1465, Host, macOS)
|
||||
* Fix backlight name detection on FreeBSD (Brightness, FreeBSD)
|
||||
* Fix Terminal detection when running fastfetch in `pk-command-not-found` (#1467, Terminal, Linux)
|
||||
* Relax detection of terminals in NixOS (#1479, Terminal, Linux)
|
||||
* Should fix konsole, ghostty and maybe others
|
||||
* Fix core count output in multi-package platforms (CPU)
|
||||
* Don't suppress the output of `preRun` (#1489)
|
||||
* Fix battery percentage detection (Battery, NetBSD)
|
||||
|
||||
Features:
|
||||
* Support ghostty terminal font detection (TerminalFont, Linux / macOS)
|
||||
* Support `kitty-icat` image protocol, which uses `kitten icat` to generate image data
|
||||
* Pros: support tmux; support gif animations; good performance
|
||||
* Cons: due to the limitation of `kitten icat`, we need to clear the screen before displaying the image logo
|
||||
* Support WM version detection (WM)
|
||||
* In Linux, Hyprland & sway are supported currently
|
||||
* Improve performance when stdout is redirected (TerminalSize)
|
||||
* Report thermal zone temp if CPU temp is not available (CPU, Linux)
|
||||
* Report sound server (Pipewire or PulseAudio) if available (#1454, Sound, Linux)
|
||||
* Enable OpenGL & OpenCL detection on Android (OpenGL / OpenCL, Android)
|
||||
* Detect & report MediaTek Dimensity 9000+ SOC name (CPU, Android)
|
||||
* Support appman (am-user) package manager detection (Packages, Linux)
|
||||
|
||||
Logo:
|
||||
* Add Lubuntu
|
||||
* Update Xray_os
|
||||
* Add SnigdhaOS
|
||||
* Add Rhino Linux
|
||||
|
||||
# 2.33.0
|
||||
|
||||
Changes:
|
||||
* Introduce a new CMake flag `-DBUILD_FLASHFETCH=OFF` to disable building flashfetch binaries
|
||||
* Package managers are encouraged to enable it. See <https://github.com/fastfetch-cli/fastfetch/discussions/627> for detail
|
||||
|
||||
Bugfixes:
|
||||
* Fix interconnect type detection (#1453, PhysicalDisk, Linux)
|
||||
* Regression of v2.28
|
||||
* Don't report `proot` as terminal (Terminal, Android)
|
||||
* Remove a debug output (DiskIO, OpenBSD)
|
||||
* Fix media detection for some players (#1461, Media, Linux)
|
||||
* Regression of v2.32
|
||||
|
||||
Features:
|
||||
* Use `$POWERSHELL_VERSION` as PowerShell version if available (Shell, Windows)
|
||||
* Fetching Windows PowerShell version can be very slow. Add `$env:POWERSHELL_VERSION = $PSVersionTable.PSVersion.ToString()` in `$PROFILE` before running `fastfetch` to improve the performance of `Shell` module
|
||||
* Add support for ubuntu-based armbian detection (#1447, OS, Linux)
|
||||
* Improve performance of Bluetooth detection (Bluetooth)
|
||||
* We no longer report disconnected bluetooth devices in `--format json` when `--bluetooth-show-disconnected` isn't specified
|
||||
* Support brightness level detection for builtin displays (Brightness, OpenBSD / NetBSD)
|
||||
* Requires root permission on OpenBSD
|
||||
* Support battery level detection (Battery, OpenBSD / NetBSD)
|
||||
* Support CPU temperature detection in NetBSD (CPU, NetBSD)
|
||||
* Hard code path of `libvulkan.so` for Android
|
||||
* So that users don't need to install the vulkan-loader wrapper of termux
|
||||
|
||||
Logo:
|
||||
* Add NurOS
|
||||
* Add GoralixOS
|
||||
|
||||
# 2.32.1
|
||||
|
||||
A hotfix for OpenBSD. No changes to other platforms.
|
||||
|
||||
Bugfixes:
|
||||
* Fix package count detection on OpenBSD (Packages, OpenBSD)
|
||||
|
||||
# 2.32.0
|
||||
|
||||
Bugfixes:
|
||||
* Fix `pci.ids` file location on OpenBSD (GPU, OpenBSD)
|
||||
* It's normally unused because enumerating PCI devices on OpenBSD requires root privileges
|
||||
* Fix bssid formatting (Wifi, Linux)
|
||||
* Fix Linux Lite distro detection (#1434, OS, Linux)
|
||||
* Suppress XE driver warnings from Mesa (#1435, OpenGL, Linux)
|
||||
* Fix format parameter name (#1443, Version)
|
||||
* Don't report useless information when Wifi is disabled (Wifi, FreeBSD)
|
||||
* Currently there are issues when the SSID contains whitespaces. More fixes are expected in the future.
|
||||
* Always use physical size reported by X11 server to avoid inconsistent results (#1444, Display, Linux)
|
||||
|
||||
Features:
|
||||
* Randomly select one if the logo source expands to multiple files (#1426, Logo)
|
||||
* Report mac product name when running Linux in MacBook (Host, Linux / FreeBSD)
|
||||
* Use screen size reported in DTD if make sense (Display)
|
||||
* Detect Virtualized Apple Silicon CPUs (CPU, Linux)
|
||||
* Add detection support for fvwm and ctwm (WM, OpenBSD / NetBSD)
|
||||
* Add Armbian-unofficial detection (OS, Linux)
|
||||
* Prefer surfaceless display when connect EGL (OpenGL)
|
||||
* Improve accuracy of WM detection on FreeBSD (WM, FreeBSD)
|
||||
* Add ratpoison window manager (WM, Linux)
|
||||
|
||||
Logo:
|
||||
* Update Linux Lite
|
||||
* Add Serpent OS
|
||||
* Add Ultramarine Small
|
||||
* Update Debian
|
||||
|
||||
# 2.31.0
|
||||
|
||||
Bugfixes:
|
||||
|
||||
+172
-40
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.31.0
|
||||
VERSION 2.36.1
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -30,6 +30,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
|
||||
set(DragonFly TRUE CACHE BOOL "..." FORCE)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
|
||||
set(SunOS TRUE CACHE BOOL "..." FORCE)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku")
|
||||
set(Haiku TRUE CACHE BOOL "..." FORCE)
|
||||
elseif(NOT APPLE AND NOT WIN32)
|
||||
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
@@ -70,12 +72,12 @@ cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR F
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly" OFF)
|
||||
@@ -86,6 +88,7 @@ cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR Open
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
|
||||
option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary
|
||||
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
||||
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
|
||||
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
|
||||
@@ -133,12 +136,12 @@ else()
|
||||
message(STATUS "Threads type: disabled")
|
||||
endif()
|
||||
|
||||
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
|
||||
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type -Werror=vla")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
|
||||
|
||||
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
|
||||
if(WIN32 OR Haiku OR ENABLE_DIRECTX_HEADERS)
|
||||
enable_language(CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
||||
@@ -502,6 +505,7 @@ if(LINUX)
|
||||
src/detection/gpu/gpu_pci.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/host/host_linux.c
|
||||
src/detection/host/host_mac.c
|
||||
src/detection/icons/icons_linux.c
|
||||
src/detection/initsystem/initsystem_linux.c
|
||||
src/detection/keyboard/keyboard_linux.c
|
||||
@@ -532,7 +536,7 @@ if(LINUX)
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_linux.c
|
||||
src/detection/wifi/wifi_linux.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/wm/wm_linux.c
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
@@ -615,8 +619,7 @@ elseif(FreeBSD)
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_bsd.c
|
||||
src/detection/bios/bios_bsd.c
|
||||
src/detection/bluetooth/bluetooth_linux.c
|
||||
src/detection/bluetoothradio/bluetoothradio_linux.c
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/board/board_bsd.c
|
||||
src/detection/bootmgr/bootmgr_bsd.c
|
||||
src/detection/brightness/brightness_bsd.c
|
||||
@@ -649,6 +652,7 @@ elseif(FreeBSD)
|
||||
src/detection/gpu/gpu_pci.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/host/host_bsd.c
|
||||
src/detection/host/host_mac.c
|
||||
src/detection/lm/lm_linux.c
|
||||
src/detection/icons/icons_linux.c
|
||||
src/detection/initsystem/initsystem_linux.c
|
||||
@@ -687,6 +691,15 @@ elseif(FreeBSD)
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
if(DragonFly)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
)
|
||||
else()
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/bluetooth/bluetooth_bsd.c
|
||||
)
|
||||
endif()
|
||||
elseif(NetBSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/dbus.c
|
||||
@@ -695,13 +708,13 @@ elseif(NetBSD)
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/battery/battery_nbsd.c
|
||||
src/detection/bios/bios_nbsd.c
|
||||
src/detection/bluetooth/bluetooth_linux.c
|
||||
src/detection/bluetoothradio/bluetoothradio_linux.c
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/board/board_nbsd.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/brightness/brightness_nosupport.c
|
||||
src/detection/brightness/brightness_nbsd.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_nbsd.c
|
||||
src/detection/cpu/cpu_nbsd.c
|
||||
@@ -741,7 +754,7 @@ elseif(NetBSD)
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_nosupport.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_obsd.c
|
||||
src/detection/memory/memory_nbsd.c
|
||||
src/detection/mouse/mouse_nosupport.c
|
||||
src/detection/netio/netio_bsd.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
@@ -750,7 +763,7 @@ elseif(NetBSD)
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_nbsd.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
src/detection/sound/sound_linux.c
|
||||
src/detection/sound/sound_nbsd.c
|
||||
src/detection/swap/swap_obsd.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
@@ -777,13 +790,13 @@ elseif(OpenBSD)
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/battery/battery_obsd.c
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/bluetooth/bluetooth_linux.c
|
||||
src/detection/bluetoothradio/bluetoothradio_linux.c
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/brightness/brightness_nosupport.c
|
||||
src/detection/brightness/brightness_obsd.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_obsd.c
|
||||
@@ -832,7 +845,7 @@ elseif(OpenBSD)
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_obsd.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
src/detection/sound/sound_linux.c
|
||||
src/detection/sound/sound_obsd.c
|
||||
src/detection/swap/swap_obsd.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
@@ -881,6 +894,7 @@ elseif(APPLE)
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/gpu/gpu_apple.m
|
||||
src/detection/host/host_apple.c
|
||||
src/detection/host/host_mac.c
|
||||
src/detection/icons/icons_nosupport.c
|
||||
src/detection/initsystem/initsystem_linux.c
|
||||
src/detection/keyboard/keyboard_apple.c
|
||||
@@ -910,7 +924,7 @@ elseif(APPLE)
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_apple.m
|
||||
src/detection/wifi/wifi_apple.m
|
||||
src/detection/wm/wm_apple.c
|
||||
src/detection/wm/wm_apple.m
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/camera/camera_apple.m
|
||||
@@ -949,6 +963,7 @@ elseif(WIN32)
|
||||
src/detection/dns/dns_windows.c
|
||||
src/detection/font/font_windows.c
|
||||
src/detection/gpu/gpu_windows.c
|
||||
src/detection/host/host_mac.c
|
||||
src/detection/host/host_windows.c
|
||||
src/detection/icons/icons_windows.c
|
||||
src/detection/initsystem/initsystem_nosupport.c
|
||||
@@ -990,6 +1005,7 @@ elseif(WIN32)
|
||||
src/util/windows/registry.c
|
||||
src/util/windows/unicode.c
|
||||
src/util/windows/wmi.cpp
|
||||
src/util/windows/version.c
|
||||
src/util/platform/FFPlatform_windows.c
|
||||
src/util/binary_windows.c
|
||||
)
|
||||
@@ -1074,6 +1090,74 @@ elseif(SunOS)
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(Haiku)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/io/io_unix.c
|
||||
src/common/netif/netif_haiku.c
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/brightness/brightness_nosupport.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_nosupport.c
|
||||
src/detection/cpucache/cpucache_nosupport.c
|
||||
src/detection/cpuusage/cpuusage_nosupport.c
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/disk/disk_nosupport.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
||||
src/detection/diskio/diskio_nosupport.c
|
||||
src/detection/displayserver/displayserver_haiku.cpp
|
||||
src/detection/font/font_haiku.cpp
|
||||
src/detection/gpu/gpu_nosupport.c
|
||||
src/detection/gpu/gpu_pci.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/host/host_nosupport.c
|
||||
src/detection/icons/icons_nosupport.c
|
||||
src/detection/initsystem/initsystem_nosupport.c
|
||||
src/detection/keyboard/keyboard_nosupport.c
|
||||
src/detection/libc/libc_nosupport.c
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/loadavg/loadavg_nosupport.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_nosupport.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/memory/memory_haiku.c
|
||||
src/detection/mouse/mouse_nosupport.c
|
||||
src/detection/netio/netio_nosupport.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_haiku.c
|
||||
src/detection/packages/packages_haiku.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_haiku.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
src/detection/sound/sound_nosupport.c
|
||||
src/detection/swap/swap_haiku.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/terminalsize/terminalsize_linux.c
|
||||
src/detection/theme/theme_nosupport.c
|
||||
src/detection/tpm/tpm_nosupport.c
|
||||
src/detection/uptime/uptime_haiku.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_nosupport.c
|
||||
src/detection/wifi/wifi_nosupport.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/detection/camera/camera_nosupport.c
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DIRECTX_HEADERS)
|
||||
@@ -1098,6 +1182,9 @@ endif()
|
||||
if(LINUX)
|
||||
check_function_exists(statx HAVE_STATX)
|
||||
endif()
|
||||
if(NOT WIN32)
|
||||
check_function_exists(pipe2 HAVE_PIPE2)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SYSTEM_YYJSON)
|
||||
find_package(yyjson)
|
||||
@@ -1128,6 +1215,14 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/vendor/lib64 -Wl,-rpath,/system/lib64")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/vendor/lib -Wl,-rpath,/system/lib")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LINUX AND EXISTS "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1")
|
||||
execute_process(COMMAND "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1"
|
||||
ERROR_VARIABLE LD_MUSL_RESULT)
|
||||
@@ -1184,6 +1279,8 @@ elseif(NetBSD)
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R7/lib -Wl,-rpath,/usr/pkg/lib") # ditto
|
||||
elseif(Haiku)
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||
endif()
|
||||
|
||||
if(FreeBSD OR OpenBSD OR NetBSD)
|
||||
@@ -1204,6 +1301,10 @@ if(HAVE_WCWIDTH)
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_WCWIDTH)
|
||||
endif()
|
||||
|
||||
if(HAVE_PIPE2)
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_PIPE2)
|
||||
endif()
|
||||
|
||||
if(NOT "${CUSTOM_PCI_IDS_PATH}" STREQUAL "")
|
||||
message(STATUS "Custom file path of pci.ids: ${CUSTOM_PCI_IDS_PATH}")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_PCI_IDS_PATH=${CUSTOM_PCI_IDS_PATH})
|
||||
@@ -1216,6 +1317,10 @@ if(NOT "${CUSTOM_OS_RELEASE_PATH}" STREQUAL "")
|
||||
message(STATUS "Custom file path of os_release: ${CUSTOM_OS_RELEASE_PATH}")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_OS_RELEASE_PATH=${CUSTOM_OS_RELEASE_PATH})
|
||||
endif()
|
||||
if(NOT "${CUSTOM_LSB_RELEASE_PATH}" STREQUAL "")
|
||||
message(STATUS "Custom file path of lsb_release: ${CUSTOM_LSB_RELEASE_PATH}")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_CUSTOM_LSB_RELEASE_PATH=${CUSTOM_LSB_RELEASE_PATH})
|
||||
endif()
|
||||
|
||||
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
|
||||
message(STATUS "Enabling custom link type: ${BINARY_LINK_TYPE}")
|
||||
@@ -1463,6 +1568,7 @@ elseif(FreeBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "usbhid"
|
||||
PRIVATE "bluetooth"
|
||||
)
|
||||
if(NOT DragonFly)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1477,10 +1583,12 @@ elseif(OpenBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "kvm"
|
||||
PRIVATE "sndio"
|
||||
)
|
||||
elseif(NetBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "prop"
|
||||
)
|
||||
elseif(SunOS)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1505,6 +1613,12 @@ elseif(ANDROID)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
elseif(Haiku)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "network"
|
||||
PRIVATE "be"
|
||||
PRIVATE "gnu"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(libfastfetch
|
||||
@@ -1607,41 +1721,52 @@ target_link_libraries(fastfetch
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
add_executable(flashfetch
|
||||
src/flashfetch.c
|
||||
)
|
||||
target_compile_definitions(flashfetch
|
||||
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
|
||||
)
|
||||
target_link_libraries(flashfetch
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
# Prevent fastfetch from linking to libstdc++
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
||||
set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(fastfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
target_sources(flashfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
elseif(APPLE)
|
||||
target_link_options(fastfetch
|
||||
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
|
||||
)
|
||||
target_link_options(flashfetch
|
||||
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BINARY_LINK_TYPE STREQUAL "static")
|
||||
target_link_options(fastfetch PRIVATE "-static")
|
||||
target_link_options(flashfetch PRIVATE "-static")
|
||||
endif()
|
||||
|
||||
# Apply all above parameters to flashfetch if it is built
|
||||
if (BUILD_FLASHFETCH)
|
||||
add_executable(flashfetch
|
||||
src/flashfetch.c
|
||||
)
|
||||
target_compile_definitions(flashfetch
|
||||
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
|
||||
)
|
||||
target_link_libraries(flashfetch
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(flashfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
elseif(APPLE)
|
||||
target_link_options(flashfetch
|
||||
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BINARY_LINK_TYPE STREQUAL "static")
|
||||
target_link_options(flashfetch PRIVATE "-static")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
###################
|
||||
@@ -1683,10 +1808,17 @@ endif()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
TARGETS fastfetch flashfetch
|
||||
TARGETS fastfetch
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
|
||||
if (TARGET flashfetch)
|
||||
install(
|
||||
TARGETS flashfetch
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if (TARGET ffwinrt)
|
||||
install(
|
||||
TARGETS ffwinrt
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2023 Linus Dierheimer
|
||||
Copyright (c) 2022-2024 Carter Li
|
||||
Copyright (c) 2022-2025 Carter Li
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -73,6 +73,10 @@ You may also download the program directly from [the GitHub releases page](https
|
||||
|
||||
* `pkg install fastfetch`
|
||||
|
||||
### Nightly
|
||||
|
||||
<https://nightly.link/fastfetch-cli/fastfetch/workflows/ci/dev?preview>
|
||||
|
||||
## Build from source
|
||||
|
||||
See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
@@ -199,10 +203,43 @@ Try upgrading `pci.ids`: Download <https://pci-ids.ucw.cz/v2.2/pci.ids> and over
|
||||
|
||||
Alternatively, you may try to use `fastfetch --gpu-driver-specific`, so that `fastfetch` will try to ask the driver for GPU name if supported.
|
||||
|
||||
### Q: I get error `Authorization required, but no authorization protocol specified` when running fastfetch in root
|
||||
|
||||
Try `export XAUTHORITY=$HOME/.Xauthority`
|
||||
|
||||
### Q: Fastfetch cannot detect my awesome 3rd-party macOS window manager!
|
||||
|
||||
Try `fastfetch --wm-detect-plugin`. See also [#984](https://github.com/fastfetch-cli/fastfetch/issues/984)
|
||||
|
||||
### Q: How can I change the colors of my ASCII logo?
|
||||
|
||||
Try `fastfetch --logo-color-[1-9] <color>`. `[1-9]` is the index of color placeholders.
|
||||
|
||||
For example: `fastfetch --logo-color-1 red --logo-color-2 green`.
|
||||
|
||||
In JSONC, you can use:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"logo": {
|
||||
"color": {
|
||||
"1": "red",
|
||||
"2": "green"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Q: How to hide a key?
|
||||
|
||||
Set the key to a white space.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"key": " "
|
||||
}
|
||||
```
|
||||
|
||||
### Q: I want feature A / B / C. Will fastfetch support it?
|
||||
|
||||
Fastfetch is a system information tool. We only accept hardware or system level software feature requests. For most personal uses, I recommend using `Command` module to detect it yourself, which can be used to grab output from a custom shell script:
|
||||
|
||||
Vendored
+42
@@ -1,3 +1,45 @@
|
||||
fastfetch (2.36.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.36.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 10 Feb 2025 10:13:53 +0800
|
||||
|
||||
fastfetch (2.35.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.35.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Sun, 26 Jan 2025 10:15:22 +0800
|
||||
|
||||
fastfetch (2.34.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.34.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 13 Jan 2025 16:06:22 +0800
|
||||
|
||||
fastfetch (2.34.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.34.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 09 Jan 2025 09:03:17 +0800
|
||||
|
||||
fastfetch (2.33.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.33.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 26 Dec 2024 09:42:27 +0800
|
||||
|
||||
fastfetch (2.32.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.32.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 18 Dec 2024 10:39:06 +0800
|
||||
|
||||
fastfetch (2.31.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.31.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 04 Dec 2024 08:41:40 +0800
|
||||
|
||||
fastfetch (2.30.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.30.1
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.30.1_source.buildinfo universe/utils optional
|
||||
fastfetch_2.36.0_source.buildinfo universe/utils optional
|
||||
|
||||
+1407
-243
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"separator": "│ ",
|
||||
"percent": {
|
||||
"type": 6
|
||||
"type": ["bar", "hide-others"]
|
||||
},
|
||||
"bar": {
|
||||
"borderLeft": "",
|
||||
@@ -70,7 +70,7 @@
|
||||
"type": "localip",
|
||||
"key": "│ MAC ADDR │{$1}",
|
||||
"format": "{mac} ({ifname})",
|
||||
"showIPv4": false,
|
||||
"showIpv4": false,
|
||||
"showMac": true
|
||||
},
|
||||
{
|
||||
@@ -120,12 +120,18 @@
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ MEMORY │{$1}",
|
||||
"format": "{used} / {total} [{percentage}]"
|
||||
"format": "{used} / {total} [{percentage}]",
|
||||
"percent": {
|
||||
"type": ["num"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ USAGE │{$1}",
|
||||
"format": ""
|
||||
"format": "",
|
||||
"percent": {
|
||||
"type": ["bar", "hide-others"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
@@ -135,12 +141,18 @@
|
||||
"type": "disk",
|
||||
"key": "│ VOLUME │{$1}",
|
||||
"format": "{size-used} / {size-total} [{size-percentage}]",
|
||||
"folders": "/"
|
||||
"folders": "/",
|
||||
"percent": {
|
||||
"type": ["num"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "│ DISK USAGE │{$1}",
|
||||
"format": ""
|
||||
"format": "",
|
||||
"percent": {
|
||||
"type": ["bar", "hide-others"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ optionSection = r"""
|
||||
Parsing is not case sensitive. E.g. \fB--logo-type\fR is
|
||||
equal to \fB--LOGO-TYPE\fR.
|
||||
|
||||
If a value is between square brakets, it is optional.
|
||||
If a value is between square brackets, it is optional.
|
||||
An optional boolean value defaults to true if not specified.
|
||||
|
||||
More detailed help messages for each options can be printed
|
||||
|
||||
+20
-11
@@ -259,24 +259,33 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
//test for constant, if so evaluate it
|
||||
//test for constant or env var, if so evaluate it
|
||||
if (firstChar == '$')
|
||||
{
|
||||
char* pend = NULL;
|
||||
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
|
||||
uint32_t index = (uint32_t) indexSigned;
|
||||
bool backward = indexSigned < 0;
|
||||
|
||||
if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index)
|
||||
if (pend == placeholderValue.chars + 1)
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
// treat placeholder as an environment variable
|
||||
char* envValue = getenv(placeholderValue.chars + 1);
|
||||
if (envValue)
|
||||
ffStrbufAppendS(buffer, envValue);
|
||||
else
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// treat placeholder as a constant
|
||||
uint32_t index = (uint32_t) (indexSigned < 0 ? (int32_t) instance.config.display.constants.length + indexSigned : indexSigned - 1);
|
||||
|
||||
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward
|
||||
? instance.config.display.constants.length - index
|
||||
: index - 1);
|
||||
ffStrbufAppend(buffer, item);
|
||||
if (*pend != '\0' || instance.config.display.constants.length <= index)
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
else
|
||||
{
|
||||
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, index);
|
||||
ffStrbufAppend(buffer, item);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -42,7 +42,5 @@ typedef struct FFformatarg
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
|
||||
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
|
||||
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, numArgs, arguments) do {\
|
||||
static_assert(sizeof(arguments) / sizeof(*arguments) == (numArgs), "Invalid number of format arguments");\
|
||||
ffParseFormatString((buffer), (formatstr), (numArgs), (arguments));\
|
||||
} while (0)
|
||||
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, arguments) \
|
||||
ffParseFormatString((buffer), (formatstr), sizeof(arguments) / sizeof(*arguments), (arguments));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "io.h"
|
||||
#include "fastfetch.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "common/time.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
@@ -145,10 +146,10 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
|
||||
if (wordexp(in, &exp, 0) != 0)
|
||||
return false;
|
||||
|
||||
if (exp.we_wordc == 1)
|
||||
if (exp.we_wordc >= 1)
|
||||
{
|
||||
result = true;
|
||||
ffStrbufSetS(out, exp.we_wordv[0]);
|
||||
ffStrbufSetS(out, exp.we_wordv[exp.we_wordc > 1 ? ffTimeGetNow() % exp.we_wordc : 0]);
|
||||
}
|
||||
|
||||
wordfree(&exp);
|
||||
@@ -159,10 +160,10 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
|
||||
if (glob(in, GLOB_NOSORT | GLOB_TILDE, NULL, &gb) != 0)
|
||||
return false;
|
||||
|
||||
if (gb.gl_matchc == 1)
|
||||
if (gb.gl_matchc >= 1)
|
||||
{
|
||||
result = true;
|
||||
ffStrbufSetS(out, gb.gl_pathv[0]);
|
||||
ffStrbufSetS(out, gb.gl_pathv[gb.gl_matchc > 1 ? ffTimeGetNow() % gb.gl_matchc : 0]);
|
||||
}
|
||||
|
||||
globfree(&gb);
|
||||
@@ -309,7 +310,7 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
||||
continue;
|
||||
|
||||
bool isDir = false;
|
||||
#ifndef __sun
|
||||
#if !defined(__sun) && !defined(__HAIKU__)
|
||||
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
|
||||
isDir = entry->d_type == DT_DIR;
|
||||
else
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "netif.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// loosely based on Haiku's src/bin/network/route/route.cpp
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
{
|
||||
// TODO: AF_INET6
|
||||
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET);
|
||||
if (pfRoute < 0)
|
||||
return false;
|
||||
|
||||
struct ifconf config;
|
||||
config.ifc_len = sizeof(config.ifc_value);
|
||||
if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
|
||||
return false;
|
||||
|
||||
int size = config.ifc_value;
|
||||
if (size == 0)
|
||||
return false;
|
||||
|
||||
FF_AUTO_FREE void *buffer = malloc(size);
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
config.ifc_len = size;
|
||||
config.ifc_buf = buffer;
|
||||
if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
|
||||
return false;
|
||||
|
||||
struct ifreq *interface = (struct ifreq*)buffer;
|
||||
struct ifreq *end = (struct ifreq*)((uint8_t*)buffer + size);
|
||||
|
||||
while (interface < end) {
|
||||
if (interface->ifr_route.flags & RTF_DEFAULT) {
|
||||
strlcpy(iface, interface->ifr_name, IF_NAMESIZE);
|
||||
*ifIndex = if_nametoindex(interface->ifr_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t addressSize = 0;
|
||||
if (interface->ifr_route.destination != NULL)
|
||||
addressSize += interface->ifr_route.destination->sa_len;
|
||||
if (interface->ifr_route.mask != NULL)
|
||||
addressSize += interface->ifr_route.mask->sa_len;
|
||||
if (interface->ifr_route.gateway != NULL)
|
||||
addressSize += interface->ifr_route.gateway->sa_len;
|
||||
|
||||
interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE
|
||||
+ sizeof(struct route_entry) + addressSize);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
+15
-23
@@ -6,6 +6,20 @@ struct yyjson_val;
|
||||
struct yyjson_mut_doc;
|
||||
struct yyjson_mut_val;
|
||||
|
||||
typedef struct FFModuleFormatArg
|
||||
{
|
||||
const char* desc;
|
||||
const char* name;
|
||||
} FFModuleFormatArg;
|
||||
|
||||
typedef struct FFModuleFormatArgList
|
||||
{
|
||||
FFModuleFormatArg* args;
|
||||
uint32_t count;
|
||||
} FFModuleFormatArgList;
|
||||
|
||||
#define FF_FORMAT_ARG_LIST(list) { .args = list, .count = sizeof(list) / sizeof(FFModuleFormatArg) }
|
||||
|
||||
// Must be the first field of FFModuleOptions
|
||||
typedef struct FFModuleBaseInfo
|
||||
{
|
||||
@@ -19,32 +33,10 @@ typedef struct FFModuleBaseInfo
|
||||
void (*parseJsonObject)(void* options, struct yyjson_val *module);
|
||||
void (*printModule)(void* options);
|
||||
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
|
||||
void (*printHelpFormat)(void);
|
||||
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
|
||||
FFModuleFormatArgList formatArgs;
|
||||
} FFModuleBaseInfo;
|
||||
|
||||
static inline void ffOptionInitModuleBaseInfo(
|
||||
FFModuleBaseInfo* baseInfo,
|
||||
const char* name,
|
||||
const char* description,
|
||||
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
|
||||
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
|
||||
void* printModule, // void (*const printModule)(void* options)
|
||||
void* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
void (*printHelpFormat)(void),
|
||||
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
)
|
||||
{
|
||||
baseInfo->name = name;
|
||||
baseInfo->description = description;
|
||||
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
|
||||
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
|
||||
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
|
||||
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
|
||||
baseInfo->printHelpFormat = printHelpFormat;
|
||||
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
|
||||
}
|
||||
|
||||
typedef enum __attribute__((__packed__)) FFModuleKeyType
|
||||
{
|
||||
FF_MODULE_KEY_TYPE_NONE = 0,
|
||||
|
||||
+1
-16
@@ -50,7 +50,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 2, ((FFformatarg[]){
|
||||
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, ((FFformatarg[]) {
|
||||
FF_FORMAT_ARG(moduleIndex, "index"),
|
||||
FF_FORMAT_ARG(moduleArgs->keyIcon, "icon"),
|
||||
}));
|
||||
@@ -148,18 +148,3 @@ void ffPrintCharTimes(char c, uint32_t times)
|
||||
if(remaining > 0)
|
||||
fwrite(str, 1, remaining, stdout);
|
||||
}
|
||||
|
||||
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[])
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(name);
|
||||
ffStrbufLowerCase(&buffer);
|
||||
printf("--%s-format:\n", buffer.chars);
|
||||
printf("Sets the format string for %s output.\n", name);
|
||||
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
|
||||
puts("The following values are passed:");
|
||||
|
||||
for(unsigned i = 0; i < numArgs; i++)
|
||||
printf(" {%u}: %s\n", i + 1, args[i]);
|
||||
|
||||
printf("The default is something similar to \"%s\".\n", def);
|
||||
}
|
||||
|
||||
+2
-10
@@ -14,16 +14,8 @@ typedef enum __attribute__((__packed__)) FFPrintType {
|
||||
|
||||
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
|
||||
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
|
||||
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, numArgs, arguments) do {\
|
||||
static_assert(sizeof(arguments) / sizeof(*arguments) == (numArgs), "Invalid number of format arguments");\
|
||||
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (numArgs), (arguments));\
|
||||
} while (0)
|
||||
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, arguments) \
|
||||
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (sizeof(arguments) / sizeof(*arguments)), (arguments));
|
||||
FF_C_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
|
||||
void ffPrintColor(const FFstrbuf* colorValue);
|
||||
void ffPrintCharTimes(char c, uint32_t times);
|
||||
|
||||
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
|
||||
#define FF_PRINT_MODULE_FORMAT_HELP_CHECKED(moduleName, def, numArgs, args) do {\
|
||||
static_assert(sizeof(args) / sizeof(*args) == (numArgs), "Invalid number of format arguments");\
|
||||
ffPrintModuleFormatHelp((moduleName), (def), (numArgs), (args));\
|
||||
} while (0)
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
|
||||
static inline int ffPipe2(int *fds, int flags)
|
||||
static inline int ffPipe2(int* fds, int flags)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
#ifndef FF_HAVE_PIPE2
|
||||
if(pipe(fds) == -1)
|
||||
return -1;
|
||||
fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | flags);
|
||||
@@ -301,7 +301,12 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
||||
if (proc)
|
||||
{
|
||||
char** argv = kvm_getargv(kd, proc, 0);
|
||||
if (argv) ffStrbufSetS(exe, argv[0]);
|
||||
if (argv)
|
||||
{
|
||||
const char* arg0 = argv[0];
|
||||
if (arg0[0] == '-') arg0++;
|
||||
ffStrbufSetS(exe, arg0);
|
||||
}
|
||||
}
|
||||
kvm_close(kd);
|
||||
|
||||
|
||||
@@ -169,6 +169,9 @@ bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFst
|
||||
? GetCurrentProcess()
|
||||
: OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||
|
||||
if (hProcess == NULL)
|
||||
return false;
|
||||
|
||||
if (gui)
|
||||
*gui = GetGuiResources(hProcess, GR_GDIOBJECTS) > 0;
|
||||
|
||||
|
||||
+12
-4
@@ -36,11 +36,19 @@
|
||||
#if FF_HAVE_PTHREAD_NP
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t FFThreadMutex;
|
||||
typedef pthread_t FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
|
||||
#if __APPLE__
|
||||
#include <os/lock.h>
|
||||
#define FF_THREAD_MUTEX_INITIALIZER OS_UNFAIR_LOCK_INIT
|
||||
typedef os_unfair_lock FFThreadMutex;
|
||||
static inline void ffThreadMutexLock(os_unfair_lock* mutex) { os_unfair_lock_lock(mutex); }
|
||||
static inline void ffThreadMutexUnlock(os_unfair_lock* mutex) { os_unfair_lock_unlock(mutex); }
|
||||
#else
|
||||
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t FFThreadMutex;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
|
||||
#endif
|
||||
static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) {
|
||||
FFThreadType newThread = 0;
|
||||
pthread_create(&newThread, NULL, func, data);
|
||||
|
||||
+10
-1
@@ -186,7 +186,8 @@
|
||||
"data-raw": "Text data, printed as is",
|
||||
"sixel": "Image file, printed as sixel codes",
|
||||
"kitty": "Image file, printed as kitty graphics protocol",
|
||||
"kitty_direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
|
||||
"kitty-direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
|
||||
"kitty-icat": "Image file, use `kitten icat` to display the image. Requires binary `kitten` to be installed",
|
||||
"iterm": "Image file, printed as iterm graphics protocol",
|
||||
"chafa": "Image file, printed as ascii art using libchafa",
|
||||
"raw": "Image file, printed as raw binary string",
|
||||
@@ -351,6 +352,14 @@
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "kitty-icat",
|
||||
"desc": "Short for --logo-type kitty-icat --logo <path>",
|
||||
"remark": "See \"--help logo-type\" for more info",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "iterm",
|
||||
"desc": "Short for --logo-type iterm --logo <path>",
|
||||
|
||||
@@ -21,6 +21,8 @@ In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string.
|
||||
If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string.
|
||||
If `,endIndex` is omitted or greater than the length of the string, the length of string is used.
|
||||
|
||||
In 2.36.0 or newer, `{$NUM}` can be specified to reference a constant defined in `display.constants`. `{$ENV_VAR}` can be specified to reference an environment variable.
|
||||
|
||||
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
|
||||
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
|
||||
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "battery.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <prop/prop_array.h>
|
||||
#include <prop/prop_bool.h>
|
||||
#include <prop/prop_dictionary.h>
|
||||
#include <prop/prop_object.h>
|
||||
#include <sys/envsys.h>
|
||||
#include <prop/proplib.h>
|
||||
#include <paths.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
|
||||
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
|
||||
|
||||
prop_dictionary_t root = NULL;
|
||||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
|
||||
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
||||
|
||||
bool acConnected = false;
|
||||
{
|
||||
prop_array_t acad = prop_dictionary_get(root, "acpiacad0");
|
||||
if (acad)
|
||||
{
|
||||
prop_dictionary_t dict = prop_array_get(acad, 0);
|
||||
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &acConnected);
|
||||
}
|
||||
}
|
||||
|
||||
prop_object_iterator_t itKey = prop_dictionary_iterator(root);
|
||||
for (prop_dictionary_keysym_t key; (key = prop_object_iterator_next(itKey)) != NULL; )
|
||||
{
|
||||
if (!ffStrStartsWith(prop_dictionary_keysym_value(key), "acpibat")) continue;
|
||||
|
||||
prop_array_t bat = prop_dictionary_get_keysym(root, key);
|
||||
uint32_t max = 0, curr = 0, dischargeRate = 0;
|
||||
bool charging = false, critical = false;
|
||||
prop_object_iterator_t iter = prop_array_iterator(bat);
|
||||
for (prop_dictionary_t dict; (dict = prop_object_iterator_next(iter)) != NULL;)
|
||||
{
|
||||
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
|
||||
continue;
|
||||
|
||||
const char* desc = NULL;
|
||||
if (!prop_dictionary_get_string(dict, "description", &desc))
|
||||
continue;
|
||||
|
||||
if (ffStrEquals(desc, "present"))
|
||||
{
|
||||
int value = 0;
|
||||
if (prop_dictionary_get_int(dict, "cur-value", &value) && value == 0)
|
||||
continue;
|
||||
}
|
||||
else if (ffStrEquals(desc, "charging"))
|
||||
{
|
||||
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &charging);
|
||||
}
|
||||
else if (ffStrEquals(desc, "charge"))
|
||||
{
|
||||
prop_dictionary_get_uint32(dict, "max-value", &max);
|
||||
prop_dictionary_get_uint32(dict, "cur-value", &curr);
|
||||
const char* state = NULL;
|
||||
if (prop_dictionary_get_string(dict, "state", &state) && ffStrEquals(state, "critical"))
|
||||
critical = true;
|
||||
}
|
||||
else if (ffStrEquals(desc, "discharge rate"))
|
||||
{
|
||||
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
|
||||
}
|
||||
}
|
||||
|
||||
if (max > 0)
|
||||
{
|
||||
FFBatteryResult* battery = ffListAdd(results);
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
battery->cycleCount = 0;
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->status);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffStrbufInit(&battery->serial);
|
||||
ffStrbufInit(&battery->manufactureDate);
|
||||
battery->timeRemaining = -1;
|
||||
|
||||
battery->capacity = (double) curr / (double) max * 100.;
|
||||
if (charging)
|
||||
ffStrbufAppendS(&battery->status, "Charging, ");
|
||||
else if (dischargeRate)
|
||||
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||
if (critical)
|
||||
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||
if (acConnected)
|
||||
ffStrbufAppendS(&battery->status, "AC Connected");
|
||||
ffStrbufTrimRight(&battery->status, ' ');
|
||||
ffStrbufTrimRight(&battery->status, ',');
|
||||
}
|
||||
}
|
||||
prop_object_iterator_release(itKey);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "battery.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <machine/apmvar.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* result)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int devfd = open("/dev/apm", O_RDONLY);
|
||||
|
||||
if (devfd < 0) return "open(dev/apm, O_RDONLY) failed";
|
||||
|
||||
struct apm_power_info info = {};
|
||||
|
||||
if (ioctl(devfd, APM_IOC_GETPOWER, &info) < 0)
|
||||
return "ioctl(APM_IOC_GETPOWER) failed";
|
||||
|
||||
if (info.battery_state == APM_BATTERY_ABSENT)
|
||||
return NULL;
|
||||
|
||||
FFBatteryResult* battery = (FFBatteryResult*) ffListAdd(result);
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
battery->cycleCount = 0;
|
||||
battery->timeRemaining = -1;
|
||||
battery->capacity = info.battery_life;
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->status);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffStrbufInit(&battery->serial);
|
||||
ffStrbufInit(&battery->manufactureDate);
|
||||
|
||||
if (info.ac_state == APM_AC_ON)
|
||||
ffStrbufAppendS(&battery->status, "AC Connected");
|
||||
else if (info.ac_state == APM_AC_BACKUP)
|
||||
ffStrbufAppendS(&battery->status, "Backup In Use");
|
||||
else if (info.ac_state == APM_AC_OFF)
|
||||
{
|
||||
battery->timeRemaining = (int) info.minutes_left * 60;
|
||||
ffStrbufAppendS(&battery->status, "Discharging");
|
||||
}
|
||||
|
||||
if (info.battery_state == APM_BATT_CRITICAL || info.battery_state == APM_BATT_CHARGING)
|
||||
{
|
||||
if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
|
||||
ffStrbufAppendS(&battery->status, info.battery_state == APM_BATT_CRITICAL ? "Critical" : "Charging");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -11,4 +11,4 @@ typedef struct FFBluetoothResult
|
||||
bool connected;
|
||||
} FFBluetoothResult;
|
||||
|
||||
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */);
|
||||
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@property (nonatomic) uint8_t batteryPercentSingle;
|
||||
@end
|
||||
|
||||
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
NSArray<IOBluetoothDevice*>* ioDevices = IOBluetoothDevice.pairedDevices;
|
||||
if(!ioDevices)
|
||||
@@ -18,6 +18,9 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
|
||||
for(IOBluetoothDevice* ioDevice in ioDevices)
|
||||
{
|
||||
if (!options->showDisconnected && !ioDevice.isConnected)
|
||||
continue;
|
||||
|
||||
FFBluetoothResult* device = ffListAdd(devices);
|
||||
ffStrbufInitS(&device->name, ioDevice.name.UTF8String);
|
||||
ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "bluetooth.h"
|
||||
|
||||
#define L2CAP_SOCKET_CHECKED
|
||||
#include <bluetooth.h>
|
||||
|
||||
static int enumDev(FF_MAYBE_UNUSED int sockfd, struct bt_devinfo const* dev, FFlist* devices)
|
||||
{
|
||||
FFBluetoothResult* device = ffListAdd(devices);
|
||||
ffStrbufInitS(&device->name, bt_devremote_name_gen(dev->devname, &dev->bdaddr));
|
||||
ffStrbufInitS(&device->address, bt_ntoa(&dev->bdaddr, NULL));
|
||||
ffStrbufUpperCase(&device->address);
|
||||
ffStrbufInit(&device->type);
|
||||
device->battery = 0;
|
||||
device->connected = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
// struct hostent* ent = bt_gethostent();
|
||||
if (bt_devenum((void*) enumDev, devices) < 0)
|
||||
return "bt_devenum() failed";
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include "common/dbus.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
/* Example dbus reply, striped to only the relevant parts:
|
||||
array [ //root
|
||||
@@ -44,16 +45,16 @@ array [ //root
|
||||
]
|
||||
*/
|
||||
|
||||
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
|
||||
static bool detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
|
||||
return;
|
||||
return true;
|
||||
|
||||
DBusMessageIter dictIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
|
||||
return;
|
||||
return true;
|
||||
|
||||
const char* deviceProperty;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
|
||||
@@ -74,6 +75,13 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
|
||||
}
|
||||
else if(ffStrEquals(deviceProperty, "Connected"))
|
||||
ffDBusGetBool(dbus, &dictIter, &device->connected);
|
||||
else if(ffStrEquals(deviceProperty, "Paired"))
|
||||
{
|
||||
bool paired = true;
|
||||
ffDBusGetBool(dbus, &dictIter, &paired);
|
||||
if (!paired) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
|
||||
@@ -103,32 +111,37 @@ static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFB
|
||||
|
||||
do
|
||||
{
|
||||
detectBluetoothValue(dbus, &arrayIter, device);
|
||||
bool shouldContinue = detectBluetoothValue(dbus, &arrayIter, device);
|
||||
if (!shouldContinue)
|
||||
{
|
||||
ffStrbufClear(&device->name);
|
||||
break;
|
||||
}
|
||||
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
|
||||
}
|
||||
|
||||
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
|
||||
static FFBluetoothResult* detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
DBusMessageIter dictIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
const char* objectPath;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
|
||||
|
||||
// We don't want adapter objects
|
||||
if(!ffStrContains(objectPath, "/dev_"))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
dbus->lib->ffdbus_message_iter_next(&dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
DBusMessageIter arrayIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
|
||||
@@ -145,16 +158,10 @@ static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessage
|
||||
detectBluetoothProperty(dbus, &arrayIter, device);
|
||||
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
|
||||
|
||||
if(device->name.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
ffStrbufDestroy(&device->address);
|
||||
ffStrbufDestroy(&device->type);
|
||||
--devices->length;
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
|
||||
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter, int32_t connectedCount)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
|
||||
return;
|
||||
@@ -164,11 +171,25 @@ static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIt
|
||||
|
||||
do
|
||||
{
|
||||
detectBluetoothObject(devices, dbus, &arrayIter);
|
||||
FFBluetoothResult* device = detectBluetoothObject(devices, dbus, &arrayIter);
|
||||
|
||||
if (device)
|
||||
{
|
||||
if(device->name.length == 0 || (connectedCount > 0 && !device->connected))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
ffStrbufDestroy(&device->address);
|
||||
ffStrbufDestroy(&device->type);
|
||||
--devices->length;
|
||||
}
|
||||
|
||||
if (device->connected && --connectedCount == 0)
|
||||
break;
|
||||
}
|
||||
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
|
||||
}
|
||||
|
||||
static const char* detectBluetooth(FFlist* devices)
|
||||
static const char* detectBluetooth(FFlist* devices, int32_t connectedCount)
|
||||
{
|
||||
FFDBusData dbus;
|
||||
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
|
||||
@@ -186,18 +207,43 @@ static const char* detectBluetooth(FFlist* devices)
|
||||
return "Failed to get root iterator of GetManagedObjects";
|
||||
}
|
||||
|
||||
detectBluetoothRoot(devices, &dbus, &rootIter);
|
||||
detectBluetoothRoot(devices, &dbus, &rootIter, connectedCount);
|
||||
|
||||
dbus.lib->ffdbus_message_unref(managedObjects);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t connectedDevices(void)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth");
|
||||
if(dirp == NULL)
|
||||
return 0;
|
||||
|
||||
uint32_t result = 0;
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (strchr(entry->d_name, ':') != NULL)
|
||||
++result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
|
||||
const char* ffDetectBluetooth(FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
#ifdef FF_HAVE_DBUS
|
||||
return detectBluetooth(devices);
|
||||
int32_t connectedCount = -1;
|
||||
if (!options->showDisconnected)
|
||||
{
|
||||
connectedCount = (int32_t) connectedDevices();
|
||||
if (connectedCount == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return detectBluetooth(devices, connectedCount);
|
||||
#else
|
||||
return "Fastfetch was compiled without DBus support";
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "bluetooth.h"
|
||||
|
||||
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
|
||||
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wpointer-sign"
|
||||
|
||||
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
// Actually bluetoothapis.dll, but it's missing on Windows 7
|
||||
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
|
||||
@@ -20,13 +20,14 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
};
|
||||
HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstDevice(&(BLUETOOTH_DEVICE_SEARCH_PARAMS) {
|
||||
.fReturnConnected = TRUE,
|
||||
.fReturnRemembered = TRUE,
|
||||
.fReturnAuthenticated = TRUE,
|
||||
.fReturnUnknown = TRUE,
|
||||
.fReturnRemembered = options->showDisconnected,
|
||||
.fReturnAuthenticated = options->showDisconnected,
|
||||
.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS)
|
||||
}, &btdi);
|
||||
if(!hFind)
|
||||
{
|
||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||
return NULL;
|
||||
return "BluetoothFindFirstDevice() failed";
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ const char* ffBluetoothDetectBattery(FFlist* devices)
|
||||
on_scope_exit releaseCallResult([&] { pCallResult && pCallResult->Release(); });
|
||||
|
||||
IWbemClassObject* pResultObject = nullptr;
|
||||
if (FAILED(pCallResult->GetResultObject(WBEM_INFINITE, &pResultObject)))
|
||||
if (FAILED(pCallResult->GetResultObject((LONG) WBEM_INFINITE, &pResultObject)))
|
||||
continue;
|
||||
on_scope_exit releaseResultObject([&] { pResultObject && pResultObject->Release(); });
|
||||
|
||||
|
||||
@@ -3,56 +3,47 @@
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include "common/dbus.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
/* Example dbus reply, striped to only the relevant parts:
|
||||
array [ //root
|
||||
/* Example dbus reply:
|
||||
array [
|
||||
dict entry(
|
||||
object path "/org/bluez/hci0"
|
||||
array [
|
||||
dict entry(
|
||||
string "org.bluez.Adapter1"
|
||||
array [
|
||||
dict entry(
|
||||
string "Address"
|
||||
variant string "XX:XX:XX:XX:XX:XX"
|
||||
)
|
||||
dict entry(
|
||||
string "Name"
|
||||
variant string "xxxxxxxx"
|
||||
)
|
||||
dict entry(
|
||||
string "Powered"
|
||||
variant boolean true
|
||||
)
|
||||
dict entry(
|
||||
string "PowerState"
|
||||
variant string "on"
|
||||
)
|
||||
dict entry(
|
||||
string "Manufacturer"
|
||||
variant uint16 2
|
||||
)
|
||||
dict entry(
|
||||
string "Version"
|
||||
variant byte 12
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
string "Address"
|
||||
variant string "XX:XX:XX:XX:XX:XX"
|
||||
)
|
||||
dict entry(
|
||||
string "Name"
|
||||
variant string "xxxxxxxx"
|
||||
)
|
||||
dict entry(
|
||||
string "Powered"
|
||||
variant boolean true
|
||||
)
|
||||
dict entry(
|
||||
string "PowerState"
|
||||
variant string "on"
|
||||
)
|
||||
dict entry(
|
||||
string "Manufacturer"
|
||||
variant uint16 2
|
||||
)
|
||||
dict entry(
|
||||
string "Version"
|
||||
variant byte 12
|
||||
)
|
||||
]
|
||||
*/
|
||||
|
||||
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device)
|
||||
static const char* detectBluetoothProperty(FFBluetoothRadioResult* device, FFDBusData* dbus, DBusMessageIter* iter)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
|
||||
return;
|
||||
return "Expected dict entry";
|
||||
|
||||
DBusMessageIter dictIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
|
||||
return;
|
||||
return "Expected dict entry key to be a string";
|
||||
|
||||
const char* deviceProperty;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
|
||||
@@ -77,121 +68,73 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
|
||||
ffDBusGetBool(dbus, &dictIter, &device->discoverable);
|
||||
else if(ffStrEquals(deviceProperty, "Pairable"))
|
||||
ffDBusGetBool(dbus, &dictIter, &device->connectable);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device)
|
||||
static const char* detectBluetoothRoot(FFBluetoothRadioResult* device, const char* hciName, FFDBusData* dbus)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
|
||||
return;
|
||||
char objPath[300];
|
||||
snprintf(objPath, sizeof(objPath), "/org/bluez/%s", hciName);
|
||||
|
||||
DBusMessageIter dictIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
|
||||
DBusMessage* properties = ffDBusGetMethodReply(dbus, "org.bluez", objPath, "org.freedesktop.DBus.Properties", "GetAll", "org.bluez.Adapter1");
|
||||
if(!properties)
|
||||
return "Failed to call org.freedesktop.DBus.Properties.GetAll";
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
|
||||
return;
|
||||
|
||||
const char* propertyType;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &propertyType);
|
||||
|
||||
if(!ffStrContains(propertyType, ".Adapter"))
|
||||
return; //We don't care about other properties
|
||||
|
||||
dbus->lib->ffdbus_message_iter_next(&dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
|
||||
return;
|
||||
|
||||
DBusMessageIter arrayIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
|
||||
|
||||
do
|
||||
DBusMessageIter rootIter;
|
||||
if(!dbus->lib->ffdbus_message_iter_init(properties, &rootIter))
|
||||
{
|
||||
detectBluetoothValue(dbus, &arrayIter, device);
|
||||
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
|
||||
}
|
||||
|
||||
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
|
||||
return;
|
||||
|
||||
DBusMessageIter dictIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
|
||||
return;
|
||||
|
||||
const char* objectPath;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
|
||||
|
||||
//We want adapter objects
|
||||
if(!ffStrStartsWith(objectPath, "/org/bluez/hci") || ffStrContains(objectPath, "/dev_"))
|
||||
return;
|
||||
|
||||
dbus->lib->ffdbus_message_iter_next(&dictIter);
|
||||
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
|
||||
return;
|
||||
|
||||
DBusMessageIter arrayIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
|
||||
|
||||
FFBluetoothRadioResult* device = ffListAdd(devices);
|
||||
ffStrbufInit(&device->name);
|
||||
ffStrbufInit(&device->address);
|
||||
ffStrbufInitStatic(&device->vendor, "Unknown");
|
||||
device->lmpVersion = INT_MIN;
|
||||
device->lmpSubversion = INT_MIN;
|
||||
device->enabled = false;
|
||||
|
||||
do
|
||||
{
|
||||
detectBluetoothProperty(dbus, &arrayIter, device);
|
||||
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
|
||||
|
||||
if(device->name.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
ffStrbufDestroy(&device->address);
|
||||
--devices->length;
|
||||
dbus->lib->ffdbus_message_unref(properties);
|
||||
return "Failed to get root iterator of org.freedesktop.DBus.Properties.GetAll";
|
||||
}
|
||||
}
|
||||
|
||||
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
|
||||
{
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
|
||||
return;
|
||||
if(dbus->lib->ffdbus_message_iter_get_arg_type(&rootIter) != DBUS_TYPE_ARRAY)
|
||||
{
|
||||
dbus->lib->ffdbus_message_unref(properties);
|
||||
return "Expected array";
|
||||
}
|
||||
|
||||
DBusMessageIter arrayIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &arrayIter);
|
||||
dbus->lib->ffdbus_message_iter_recurse(&rootIter, &arrayIter);
|
||||
|
||||
do
|
||||
{
|
||||
detectBluetoothObject(devices, dbus, &arrayIter);
|
||||
detectBluetoothProperty(device, dbus, &arrayIter);
|
||||
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
|
||||
|
||||
dbus->lib->ffdbus_message_unref(properties);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectBluetooth(FFlist* devices)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth");
|
||||
if(dirp == NULL)
|
||||
return "Failed to open /sys/class/bluetooth";
|
||||
|
||||
FFDBusData dbus;
|
||||
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
DBusMessage* managedObjects = ffDBusGetMethodReply(&dbus, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", NULL);
|
||||
if(!managedObjects)
|
||||
return "Failed to call GetManagedObjects";
|
||||
|
||||
DBusMessageIter rootIter;
|
||||
if(!dbus.lib->ffdbus_message_iter_init(managedObjects, &rootIter))
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(managedObjects);
|
||||
return "Failed to get root iterator of GetManagedObjects";
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
if (strchr(entry->d_name, ':') != NULL) // ignore connected devices
|
||||
continue;
|
||||
|
||||
FFBluetoothRadioResult* device = ffListAdd(devices);
|
||||
ffStrbufInit(&device->name);
|
||||
ffStrbufInit(&device->address);
|
||||
ffStrbufInitStatic(&device->vendor, "Unknown");
|
||||
device->lmpVersion = INT_MIN;
|
||||
device->lmpSubversion = INT_MIN;
|
||||
device->enabled = false;
|
||||
detectBluetoothRoot(device, entry->d_name, &dbus);
|
||||
}
|
||||
|
||||
detectBluetoothRoot(devices, &dbus, &rootIter);
|
||||
|
||||
dbus.lib->ffdbus_message_unref(managedObjects);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -202,7 +145,7 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
||||
#ifdef FF_HAVE_DBUS
|
||||
return detectBluetooth(devices);
|
||||
#else
|
||||
FF_UNUSED(devices)
|
||||
FF_UNUSED(devices)
|
||||
return "Fastfetch was compiled without DBus support";
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ const char* ffDetectBoard(FFBoardResult* board)
|
||||
ffCleanUpSmbiosValue(&board->version);
|
||||
if (ffSysctlGetString("machdep.dmi.board-vendor", &board->vendor) == NULL)
|
||||
ffCleanUpSmbiosValue(&board->vendor);
|
||||
if (ffSysctlGetString("machdep.dmi.board-serial", &board->serial) == NULL)
|
||||
ffCleanUpSmbiosValue(&board->serial);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
|
||||
brightness->current = status.brightness;
|
||||
|
||||
struct backlight_info info;
|
||||
if(ioctl(blfd, BACKLIGHTGETINFO, &info) < 0)
|
||||
if(ioctl(blfd, BACKLIGHTGETINFO, &info) == 0)
|
||||
ffStrbufAppendS(&brightness->name, info.name);
|
||||
else
|
||||
ffStrbufAppendS(&brightness->name, path + strlen("/dev/backlight/"));
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "brightness.h"
|
||||
|
||||
#include "common/sysctl.h"
|
||||
|
||||
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
|
||||
{
|
||||
// https://man.netbsd.org/NetBSD-10.1/acpiout.4#DESCRIPTION
|
||||
char key[] = "hw.acpi.acpiout0.brightness";
|
||||
char* pn = key + strlen("hw.acpi.acpiout");
|
||||
|
||||
for (uint32_t i = 0; i <= 9; ++i)
|
||||
{
|
||||
*pn = (char) ('0' + i);
|
||||
int value = ffSysctlGetInt(key, -1);
|
||||
if (value == -1) continue;
|
||||
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
ffStrbufInitF(&brightness->name, "acpiout%d", i);
|
||||
|
||||
brightness->max = 100;
|
||||
brightness->min = 0;
|
||||
brightness->current = value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "brightness.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int devfd = open("/dev/ttyC0", O_RDONLY);
|
||||
|
||||
if (devfd < 0) return "open(dev/ttyC0, O_RDONLY) failed";
|
||||
|
||||
struct wsdisplay_param param = {
|
||||
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
|
||||
};
|
||||
|
||||
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
|
||||
return "ioctl(WSDISPLAYIO_GETPARAM) failed";
|
||||
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
ffStrbufInitStatic(&brightness->name, "wsdisplay");
|
||||
|
||||
brightness->max = param.max;
|
||||
brightness->min = param.min;
|
||||
brightness->current = param.curval;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ static const char* enumerateDevices(FFBtrfsResult* item, int dfd, FFstrbuf* buff
|
||||
ffStrbufAppendC(&item->devices, ',');
|
||||
ffStrbufAppendS(&item->devices, entry->d_name);
|
||||
|
||||
char path[ARRAY_SIZE(entry->d_name) + ARRAY_SIZE("/size") + 1];
|
||||
char path[sizeof(entry->d_name) + sizeof("/size") + 1];
|
||||
snprintf(path, ARRAY_SIZE(path), "%s/size", entry->d_name);
|
||||
|
||||
if (ffReadFileBufferRelative(subfd, path, buffer))
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
// warning: 'AVCaptureDeviceTypeExternalUnknown' is deprecated
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
#ifdef MAC_OS_VERSION_14_0
|
||||
// To make fastfetch compiled on newer macOS versions runs on older ones
|
||||
AVF_EXPORT __attribute__((weak_import)) AVCaptureDeviceType const AVCaptureDeviceTypeExternal;
|
||||
#endif
|
||||
|
||||
const char* ffDetectCamera(FFlist* result)
|
||||
{
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
|
||||
@@ -10,6 +10,8 @@ const char* ffDetectChassis(FFChassisResult* chassis)
|
||||
ffCleanUpSmbiosValue(&chassis->version);
|
||||
if (ffSysctlGetString("machdep.dmi.chassis-vendor", &chassis->vendor) == NULL)
|
||||
ffCleanUpSmbiosValue(&chassis->vendor);
|
||||
if (ffSysctlGetString("machdep.dmi.chassis-serial", &chassis->serial) == NULL)
|
||||
ffCleanUpSmbiosValue(&chassis->serial);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,14 @@ const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
const char* removeStrings[] = {
|
||||
" CPU", " FPU", " APU", " Processor",
|
||||
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
|
||||
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
|
||||
" with Radeon Graphics"
|
||||
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core"
|
||||
};
|
||||
ffStrbufRemoveStrings(&cpu->name, ARRAY_SIZE(removeStrings), removeStrings);
|
||||
uint32_t radeonGraphics = ffStrbufFirstIndexS(&cpu->name, " w/ Radeon "); // w/ Radeon 780M Graphics
|
||||
if (radeonGraphics >= cpu->name.length)
|
||||
radeonGraphics = ffStrbufFirstIndexS(&cpu->name, " with Radeon ");
|
||||
if (radeonGraphics < cpu->name.length)
|
||||
ffStrbufSubstrBefore(&cpu->name, radeonGraphics);
|
||||
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
|
||||
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
|
||||
ffStrbufRemoveDupWhitespaces(&cpu->name);
|
||||
|
||||
@@ -15,6 +15,7 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break;
|
||||
case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break;
|
||||
case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break;
|
||||
case 4: error = ffDetectSmcTemps(FF_TEMP_CPU_M4X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon CPU";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,8 @@ static const char* qcomPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "Oryon";
|
||||
case 0x001: return "Oryon 1";
|
||||
case 0x002: return "Oryon 2";
|
||||
case 0x00f: return "Scorpion";
|
||||
case 0x02d: return "Scorpion";
|
||||
case 0x04d: return "Krait";
|
||||
@@ -262,6 +263,9 @@ static const char* applePartId2name(uint32_t partId)
|
||||
case 0x037: return "Everest-A16";
|
||||
case 0x038: return "Blizzard-M2-Max";
|
||||
case 0x039: return "Avalanche-M2-Max";
|
||||
case 0x046: return "Sawtooth-M11";
|
||||
case 0x048: return "Sawtooth-M3-Max";
|
||||
case 0x049: return "Everest-M3-Max";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#include "cpu.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#if __has_include(<sys/cpuset.h>)
|
||||
#include <sys/cpuset.h>
|
||||
#define FF_HAVE_CPUSET 1
|
||||
#endif
|
||||
|
||||
static const char* detectCpuTemp(double* current)
|
||||
{
|
||||
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
|
||||
@@ -60,9 +66,19 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
}
|
||||
}
|
||||
|
||||
#if FF_HAVE_CPUSET && (__x86_64__ || __i386__)
|
||||
// Bind current process to the first two cores, which is *usually* a performance core
|
||||
cpuset_t currentCPU;
|
||||
CPU_ZERO(¤tCPU);
|
||||
CPU_SET(1, ¤tCPU);
|
||||
CPU_SET(2, ¤tCPU);
|
||||
cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), ¤tCPU);
|
||||
#endif
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
cpu->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
|
||||
uint32_t clockrate = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
|
||||
if (clockrate > cpu->frequencyBase) cpu->frequencyBase = clockrate;
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (options->temp)
|
||||
|
||||
+230
-98
@@ -10,6 +10,8 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define FF_CPUINFO_PATH "/proc/cpuinfo"
|
||||
|
||||
static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
|
||||
{
|
||||
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
|
||||
@@ -44,12 +46,20 @@ static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
|
||||
if(
|
||||
ffStrbufContainS(buffer, "cpu") ||
|
||||
ffStrbufEqualS(buffer, "k10temp") || // AMD
|
||||
ffStrbufEqualS(buffer, "fam15h_power") || // AMD
|
||||
ffStrbufEqualS(buffer, "coretemp") // Intel
|
||||
) return value / 1000.;
|
||||
|
||||
return 0.0/0.0;
|
||||
}
|
||||
|
||||
static double detectTZTemp(FFstrbuf* buffer)
|
||||
{
|
||||
if (ffReadFileBuffer("/sys/class/thermal/thermal_zone0/temp", buffer))
|
||||
return ffStrbufToDouble(buffer) / 1000.;
|
||||
return 0.0/0.0;
|
||||
}
|
||||
|
||||
static double detectCPUTemp(void)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
|
||||
@@ -79,7 +89,7 @@ static double detectCPUTemp(void)
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
return 0.0/0.0;
|
||||
return detectTZTemp(&buffer);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -89,7 +99,11 @@ static void detectQualcomm(FFCPUResult* cpu)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips
|
||||
|
||||
if (ffStrbufEqualS(&cpu->name, "SM8750"))
|
||||
if (ffStrbufEqualS(&cpu->name, "SM8750-AC"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Elite for Galaxy [SM8750-AC]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM8750-3"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Elite [SM8750-3]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM8750"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Elite [SM8750]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM8635"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8s Gen 3 [SM8635]");
|
||||
@@ -136,6 +150,36 @@ static void detectQualcomm(FFCPUResult* cpu)
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 4 Gen 1 [SM4375]");
|
||||
}
|
||||
|
||||
static void detectMediaTek(FFCPUResult* cpu)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/List_of_MediaTek_systems_on_chips
|
||||
|
||||
if (ffStrbufEqualS(&cpu->name, "MT6991"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9400 [MT6991]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6991Z"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9400 [MT6991Z]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6989Z"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300+ [MT6989Z]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT8796Z"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300+ [MT8796Z]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6989"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300 [MT6989]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT8796"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300 [MT8796]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6985W"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9200+ [MT6985W]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6985"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9200 [MT6985]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6983W"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000+ [MT6983W]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT8798Z/T"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000+ [MT8798Z/T]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT6983Z"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000 [MT6983Z]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "MT8798Z/C"))
|
||||
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000 [MT8798Z/C]");
|
||||
}
|
||||
|
||||
static void detectAndroid(FFCPUResult* cpu)
|
||||
{
|
||||
if (cpu->name.length == 0)
|
||||
@@ -153,6 +197,8 @@ static void detectAndroid(FFCPUResult* cpu)
|
||||
|
||||
if (ffStrbufEqualS(&cpu->vendor, "QTI") && ffStrbufStartsWithS(&cpu->name, "SM"))
|
||||
detectQualcomm(cpu);
|
||||
else if (ffStrbufEqualS(&cpu->vendor, "MTK") && ffStrbufStartsWithS(&cpu->name, "MT"))
|
||||
detectMediaTek(cpu);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -170,28 +216,34 @@ static void detectArmName(FFstrbuf* cpuinfo, FFCPUResult* cpu, uint32_t implId)
|
||||
if (!ffStrStartsWith(line, "CPU part\t: ")) continue;
|
||||
uint32_t partId = (uint32_t) strtoul(line + strlen("CPU part\t: "), NULL, 16);
|
||||
const char* name = NULL;
|
||||
if (partId > 0) // Linux reports 0 for unknown CPUs
|
||||
switch (implId)
|
||||
{
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: name = armPartId2name(partId); break;
|
||||
case 0x42: name = brcmPartId2name(partId); break;
|
||||
case 0x43: name = caviumPartId2name(partId); break;
|
||||
case 0x44: name = decPartId2name(partId); break;
|
||||
case 0x46: name = fujitsuPartId2name(partId); break;
|
||||
case 0x48: name = hisiPartId2name(partId); break;
|
||||
case 0x4e: name = nvidiaPartId2name(partId); break;
|
||||
case 0x50: name = apmPartId2name(partId); break;
|
||||
case 0x51: name = qcomPartId2name(partId); break;
|
||||
case 0x53: name = samsungPartId2name(partId); break;
|
||||
case 0x56: name = marvellPartId2name(partId); break;
|
||||
case 0x61: name = applePartId2name(partId); break;
|
||||
case 0x66: name = faradayPartId2name(partId); break;
|
||||
case 0x69: name = intelPartId2name(partId); break;
|
||||
case 0x6d: name = msPartId2name(partId); break;
|
||||
case 0x70: name = ftPartId2name(partId); break;
|
||||
case 0xc0: name = amperePartId2name(partId); break;
|
||||
}
|
||||
case 0x41: name = armPartId2name(partId); break;
|
||||
case 0x42: name = brcmPartId2name(partId); break;
|
||||
case 0x43: name = caviumPartId2name(partId); break;
|
||||
case 0x44: name = decPartId2name(partId); break;
|
||||
case 0x46: name = fujitsuPartId2name(partId); break;
|
||||
case 0x48: name = hisiPartId2name(partId); break;
|
||||
case 0x4e: name = nvidiaPartId2name(partId); break;
|
||||
case 0x50: name = apmPartId2name(partId); break;
|
||||
case 0x51: name = qcomPartId2name(partId); break;
|
||||
case 0x53: name = samsungPartId2name(partId); break;
|
||||
case 0x56: name = marvellPartId2name(partId); break;
|
||||
case 0x61:
|
||||
if (partId == 0)
|
||||
{
|
||||
// https://github.com/Dr-Noob/cpufetch/issues/213#issuecomment-1927782105
|
||||
ffStrbufSetStatic(&cpu->name, "Virtualized Apple Silicon");
|
||||
ffStrbufGetlineRestore(&line, &len, cpuinfo);
|
||||
return;
|
||||
}
|
||||
name = applePartId2name(partId);
|
||||
break;
|
||||
case 0x66: name = faradayPartId2name(partId); break;
|
||||
case 0x69: name = intelPartId2name(partId); break;
|
||||
case 0x6d: name = msPartId2name(partId); break;
|
||||
case 0x70: name = ftPartId2name(partId); break;
|
||||
case 0xc0: name = amperePartId2name(partId); break;
|
||||
}
|
||||
if (lastPartId != partId)
|
||||
{
|
||||
@@ -233,38 +285,46 @@ static const char* parseCpuInfo(
|
||||
while(ffStrbufGetline(&line, &len, cpuinfo))
|
||||
{
|
||||
//Stop after reasonable information is acquired
|
||||
if((*line == '\0' || *line == '\n')
|
||||
#if __arm__ || __loongarch__
|
||||
&& cpu->name.length > 0 // #1202 #1204
|
||||
#endif
|
||||
)
|
||||
if((*line == '\0' || *line == '\n') && cpu->name.length > 0)
|
||||
{
|
||||
ffStrbufGetlineRestore(&line, &len, cpuinfo);
|
||||
break;
|
||||
}
|
||||
|
||||
(void)(
|
||||
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
|
||||
// "Hardware" should always be used in this case
|
||||
#if !(__arm__ || __aarch64__)
|
||||
#if __x86_64__ || __i386__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
|
||||
(physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
|
||||
#endif
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
|
||||
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
|
||||
#endif
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
#elif __arm__ || __aarch64__
|
||||
(cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
|
||||
#elif __powerpc__ || __powerpc
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "clock :", cpuMHz)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) ||
|
||||
#elif __mips__ || __mips
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) ||
|
||||
#elif __loongarch__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Model Name :", &cpu->name)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "CPU MHz :", cpuMHz)) ||
|
||||
#elif __riscv__ || __riscv
|
||||
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
|
||||
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
|
||||
#elif __s390x__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "processor 0:", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz static :", cpuMHz)) || // This one cannot be detected because of early return
|
||||
#else
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model :", &cpu->name)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "hardware :", &cpu->name)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "processor :", &cpu->name)) ||
|
||||
#endif
|
||||
#if __powerpc__ || __powerpc
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
#endif
|
||||
#if __mips__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS
|
||||
#endif
|
||||
|
||||
false
|
||||
);
|
||||
}
|
||||
@@ -361,6 +421,59 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if __i386__ || __x86_64__
|
||||
|
||||
FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
|
||||
{
|
||||
const char* p = cpuinfo->chars;
|
||||
uint64_t low = 0, high = 0;
|
||||
|
||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
|
||||
{
|
||||
if (!p) break;
|
||||
p += strlen("\nphysical id\t:");
|
||||
char* pend;
|
||||
unsigned long id = strtoul(p, &pend, 10);
|
||||
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
|
||||
high |= 1 << (id - 64);
|
||||
else
|
||||
low |= 1 << id;
|
||||
p = pend;
|
||||
}
|
||||
|
||||
return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high));
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
|
||||
if (!ffReadFileBuffer(FF_CPUINFO_PATH, &cpuinfo) || cpuinfo.length == 0)
|
||||
return "ffReadFileBuffer(\"" FF_CPUINFO_PATH "\") failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
|
||||
const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, NULL,NULL, NULL);
|
||||
if (error) return error;
|
||||
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
cpu->packages = getPackageCount(&cpuinfo);
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, 0); // physical cores in single package
|
||||
if (cpu->coresPhysical == 0)
|
||||
cpu->coresPhysical = cpu->coresLogical;
|
||||
else if (cpu->packages > 1)
|
||||
cpu->coresPhysical *= cpu->packages;
|
||||
|
||||
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
|
||||
{
|
||||
// Always use the last part of the ISA string. Ref: #590 #1204
|
||||
@@ -383,7 +496,7 @@ FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
|
||||
}
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
|
||||
FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu)
|
||||
{
|
||||
if (cpu->name.length > 0)
|
||||
return;
|
||||
@@ -464,18 +577,20 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
|
||||
}
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
|
||||
#ifdef __loongarch__
|
||||
FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const char* key)
|
||||
{
|
||||
const char* p = cpuinfo->chars;
|
||||
uint64_t low = 0, high = 0;
|
||||
uint32_t keylen = (uint32_t) strlen(key);
|
||||
|
||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
|
||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), key, keylen)))
|
||||
{
|
||||
if (!p) break;
|
||||
p += strlen("\nphysical id\t:");
|
||||
p += keylen;
|
||||
char* pend;
|
||||
unsigned long id = strtoul(p, &pend, 10);
|
||||
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
|
||||
if (__builtin_expect(id > 64, false))
|
||||
high |= 1 << (id - 64);
|
||||
else
|
||||
low |= 1 << id;
|
||||
@@ -484,66 +599,83 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
|
||||
|
||||
return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high));
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
|
||||
if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0)
|
||||
return "ffReadFileBuffer(\"/proc/cpuinfo\") failed";
|
||||
|
||||
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
|
||||
|
||||
const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
|
||||
if (error) return error;
|
||||
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
|
||||
#if __x86_64__ || __i386__
|
||||
cpu->packages = getPackageCount(&cpuinfo);
|
||||
#endif
|
||||
|
||||
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
if(cpuUarch.length > 0)
|
||||
{
|
||||
if(cpu->name.length > 0)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuUarch);
|
||||
}
|
||||
|
||||
if(cpuIsa.length > 0)
|
||||
{
|
||||
parseIsa(&cpuIsa);
|
||||
if(cpu->name.length > 0)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuIsa);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
|
||||
ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer));
|
||||
|
||||
#if __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#else
|
||||
detectArmSoc(cpu);
|
||||
detectSocName(cpu);
|
||||
#endif
|
||||
|
||||
detectFrequency(cpu, options);
|
||||
|
||||
if (cpu->name.length == 0)
|
||||
detectArmName(&cpuinfo, cpu, cpuImplementer);
|
||||
#endif
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
|
||||
if (!ffReadFileBuffer(FF_CPUINFO_PATH, &cpuinfo) || cpuinfo.length == 0)
|
||||
return "ffReadFileBuffer(\"" FF_CPUINFO_PATH "\") failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
|
||||
|
||||
const char* error = parseCpuInfo(&cpuinfo, cpu, NULL, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
|
||||
if (error) return error;
|
||||
|
||||
if (cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
|
||||
ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer));
|
||||
|
||||
if (cpu->name.length == 0)
|
||||
detectArmName(&cpuinfo, cpu, cpuImplementer);
|
||||
#elif __riscv__ || __riscv
|
||||
if (cpu->name.length == 0)
|
||||
{
|
||||
if(cpuUarch.length > 0)
|
||||
{
|
||||
if(cpu->name.length > 0)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuUarch);
|
||||
}
|
||||
|
||||
if(cpuIsa.length > 0)
|
||||
{
|
||||
parseIsa(&cpuIsa);
|
||||
if(cpu->name.length > 0)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuIsa);
|
||||
}
|
||||
}
|
||||
#elif __loongarch__
|
||||
cpu->packages = getLoongarchPropCount(&cpuinfo, "\npackage\t\t\t:");
|
||||
cpu->coresPhysical = getLoongarchPropCount(&cpuinfo, "\ncore\t\t\t:");
|
||||
if (cpu->packages > 1) cpu->coresPhysical *= cpu->packages;
|
||||
#elif __s390x__
|
||||
if (ffStrbufSubstrAfterFirstS(&cpu->name, "machine = "))
|
||||
ffStrbufPrependS(&cpu->name, "Machine ");
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
|
||||
|
||||
#if __x86_64__ || __i386__
|
||||
return detectCPUX86(options, cpu);
|
||||
#else
|
||||
return detectCPUOthers(options, cpu);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
#include "cpu.h"
|
||||
#include "common/sysctl.h"
|
||||
#include <sys/sysctl.h>
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <sys/envsys.h>
|
||||
#include <prop/proplib.h>
|
||||
#include <paths.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static const char* detectCpuTemp(double* current)
|
||||
{
|
||||
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
|
||||
if (temp == -999999)
|
||||
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
|
||||
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
|
||||
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
|
||||
|
||||
// In tenth of degrees Kelvin
|
||||
*current = (double) temp / 10 - 273.15;
|
||||
return NULL;
|
||||
}
|
||||
prop_dictionary_t root = NULL;
|
||||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
|
||||
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
||||
|
||||
static const char* detectThermalTemp(double* current)
|
||||
{
|
||||
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
|
||||
if (temp == -999999)
|
||||
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
|
||||
prop_array_t array = prop_dictionary_get(root, "coretemp0");
|
||||
if (!array) array = prop_dictionary_get(root, "amdzentemp0");
|
||||
if (!array) array = prop_dictionary_get(root, "viac7temp0");
|
||||
if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
|
||||
if (!array) return "No temp data found in root dictionary";
|
||||
|
||||
if (prop_array_count(array) != 2)
|
||||
return "Unexpected `xtemp0` data";
|
||||
|
||||
prop_dictionary_t dict = prop_array_get(array, 0);
|
||||
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
|
||||
return "Unexpected `xtemp0[0]`";
|
||||
|
||||
int temp = 0; // in µK
|
||||
if (!prop_dictionary_get_int(dict, "cur-value", &temp))
|
||||
return "Failed to get temperature";
|
||||
|
||||
*current = temp / 1e6 - 273.15;
|
||||
|
||||
// In tenth of degrees Kelvin
|
||||
*current = (double) temp / 10 - 273.15;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -32,26 +48,21 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
return "sysctlbyname(machdep.cpu_brand) failed";
|
||||
}
|
||||
|
||||
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL)
|
||||
ffStrbufTrimRightSpace(&cpu->vendor);
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
||||
cpu->coresLogical = cpu->coresPhysical;
|
||||
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.ncpuonline", cpu->coresLogical);
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
{
|
||||
struct clockinfo info;
|
||||
size_t length = sizeof(info);
|
||||
if (sysctl((int[]) {CTL_KERN, KERN_CLOCKRATE}, 2, &info, &length, NULL, 0) == 0)
|
||||
cpu->frequencyBase = (uint32_t) info.hz / 1000;
|
||||
}
|
||||
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
|
||||
if (freq > cpu->frequencyBase) cpu->frequencyBase = freq;
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (options->temp)
|
||||
{
|
||||
if (detectCpuTemp(&cpu->temperature) != NULL)
|
||||
detectThermalTemp(&cpu->temperature);
|
||||
}
|
||||
if (options->temp) detectCpuTemp(&cpu->temperature);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
cpu->frequencyBase = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
|
||||
uint32_t cpuspeed = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
|
||||
if (cpuspeed > cpu->frequencyBase) cpu->frequencyBase = cpuspeed;
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
if (options->temp)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#ifdef __NetBSD__
|
||||
#include <sys/types.h>
|
||||
#include <sys/statvfs.h>
|
||||
#define getfsstat(...) getvfsstat(__VA_ARGS__)
|
||||
#define statfs statvfs
|
||||
#define f_flags f_flag
|
||||
#define f_bsize f_frsize
|
||||
@@ -125,18 +124,26 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk)
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
#ifndef __NetBSD__
|
||||
int size = getfsstat(NULL, 0, MNT_WAIT);
|
||||
|
||||
if(size <= 0)
|
||||
return "getfsstat(NULL, 0, MNT_WAIT) failed";
|
||||
if(size <= 0) return "getfsstat(NULL, 0, MNT_WAIT) failed";
|
||||
#else
|
||||
int size = getvfsstat(NULL, 0, ST_WAIT);
|
||||
if(size <= 0) return "getvfsstat(NULL, 0, ST_WAIT) failed";
|
||||
#endif
|
||||
|
||||
FF_AUTO_FREE struct statfs* buf = malloc(sizeof(*buf) * (unsigned) size);
|
||||
#ifndef __NetBSD__
|
||||
if(getfsstat(buf, (int) (sizeof(*buf) * (unsigned) size), MNT_NOWAIT) <= 0)
|
||||
return "getfsstat(buf, size, MNT_NOWAIT) failed";
|
||||
#else
|
||||
if(getvfsstat(buf, sizeof(*buf) * (unsigned) size, ST_NOWAIT) <= 0)
|
||||
return "getvfsstat(buf, size, ST_NOWAIT) failed";
|
||||
#endif
|
||||
|
||||
for(struct statfs* fs = buf; fs < buf + size; ++fs)
|
||||
{
|
||||
if(__builtin_expect(options->folders.length, 0))
|
||||
if(__builtin_expect(options->folders.length > 0, 0))
|
||||
{
|
||||
if(!ffDiskMatchMountpoint(options, fs->f_mntonname))
|
||||
continue;
|
||||
|
||||
@@ -99,8 +99,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
device->writeCount = current->num_writes;
|
||||
}
|
||||
|
||||
if (stats.dinfo->mem_ptr)
|
||||
free(stats.dinfo->mem_ptr);
|
||||
free(stats.dinfo->mem_ptr);
|
||||
free(stats.dinfo);
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -13,8 +13,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
return "sysctl({HW_DISKSTATS}, NULL) failed";
|
||||
uint32_t nDrive = (uint32_t) (len / sizeof(struct diskstats));
|
||||
|
||||
printf("C: %d\n", nDrive);
|
||||
|
||||
struct diskstats* stats = malloc(len);
|
||||
|
||||
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
#define FF_WM_PRETTY_ICEWM "IceWM"
|
||||
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
|
||||
#define FF_WM_PRETTY_DTWM "dtwm"
|
||||
|
||||
#define FF_WM_PRETTY_FVWM "fvwm"
|
||||
#define FF_WM_PRETTY_CTWM "ctwm"
|
||||
#define FF_WM_PRETTY_RATPOISON "ratpoison"
|
||||
|
||||
#define FF_WM_PROTOCOL_TTY "TTY"
|
||||
#define FF_WM_PROTOCOL_X11 "X11"
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
extern "C" {
|
||||
#include "displayserver.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/processing.h"
|
||||
}
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Screen.h>
|
||||
|
||||
extern "C" void ffConnectDisplayServerImpl(FFDisplayServerResult* ds);
|
||||
|
||||
static void detectDisplays(FFDisplayServerResult* ds)
|
||||
{
|
||||
// We need a valid be_app to query the app_server here.
|
||||
BApplication app("application/x-vnd.fastfetch-cli-fastfetch");
|
||||
BScreen s{}; // default screen is the main one
|
||||
bool main = true;
|
||||
|
||||
do
|
||||
{
|
||||
if (!s.IsValid())
|
||||
continue;
|
||||
|
||||
display_mode mode;
|
||||
if (s.GetMode(&mode) != B_OK)
|
||||
continue;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateA(128);
|
||||
monitor_info monitor;
|
||||
// WARNING: This is experimental new Haiku API
|
||||
status_t err = s.GetMonitorInfo(&monitor);
|
||||
if (err == B_OK) {
|
||||
ffStrbufSetF(&name, "%s %s", monitor.vendor, monitor.name);
|
||||
}
|
||||
|
||||
uint32_t width = (uint32_t) s.Frame().Width() + 1;
|
||||
uint32_t height = (uint32_t) (uint32_t)s.Frame().Height() + 1;
|
||||
double scaleFactor = (double) 1.0;
|
||||
ffdsAppendDisplay(ds,
|
||||
width,
|
||||
height,
|
||||
(double)mode.timing.pixel_clock * 1000 / (mode.timing.v_total * mode.timing.h_total),
|
||||
(uint32_t) (width / scaleFactor + .5),
|
||||
(uint32_t) (height / scaleFactor + .5),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
main,
|
||||
s.ID().id,
|
||||
0,
|
||||
0,
|
||||
"BScreen"
|
||||
);
|
||||
main = false;
|
||||
} while (s.SetToNext() == B_OK);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
{
|
||||
ffStrbufSetStatic(&ds->wmProcessName, "app_server");
|
||||
ffStrbufSetStatic(&ds->wmPrettyName, "Application Server");
|
||||
ffStrbufSetStatic(&ds->dePrettyName, "Application Kit");
|
||||
|
||||
detectDisplays(ds);
|
||||
}
|
||||
@@ -78,11 +78,11 @@ static struct zxdg_output_v1_listener zxdgOutputListener = {
|
||||
.description = (void*) ffWaylandOutputDescriptionListener,
|
||||
};
|
||||
|
||||
void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, wldata->ffwl_output_interface, version, name, wldata->ffwl_output_interface->name, version, NULL);
|
||||
if(output == NULL)
|
||||
return;
|
||||
return "Failed to create wl_output";
|
||||
|
||||
WaylandDisplay display = {
|
||||
.parent = wldata,
|
||||
@@ -94,8 +94,16 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
.edidName = ffStrbufCreate(),
|
||||
};
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to add listener to wl_output";
|
||||
}
|
||||
if (wldata->ffwl_display_roundtrip(wldata->display) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to roundtrip wl_output";
|
||||
}
|
||||
|
||||
if (wldata->zxdgOutputManager)
|
||||
{
|
||||
@@ -112,7 +120,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
|
||||
if(display.width <= 0 || display.height <= 0)
|
||||
return;
|
||||
return "Failed to get display information from wl_output";
|
||||
|
||||
uint32_t rotation = ffWaylandHandleRotation(&display);
|
||||
|
||||
@@ -156,15 +164,19 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
ffStrbufDestroy(&display.description);
|
||||
ffStrbufDestroy(&display.name);
|
||||
ffStrbufDestroy(&display.edidName);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
const char* ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, version, name, zxdg_output_manager_v1_interface.name, version, NULL);
|
||||
if(manager == NULL)
|
||||
return;
|
||||
return "Failed to create zxdg_output_manager_v1";
|
||||
|
||||
wldata->zxdgOutputManager = manager;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
/* Generated by wayland-scanner 1.23.1 */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H
|
||||
#define KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H
|
||||
@@ -53,6 +53,11 @@ struct kde_output_device_v2;
|
||||
* This object is published as global during start up for every available
|
||||
* display devices, or when one later becomes available, for example by
|
||||
* being hotplugged via a physical connector.
|
||||
*
|
||||
* Warning! The protocol described in this file is a desktop environment
|
||||
* implementation detail. Regular clients must not use this protocol.
|
||||
* Backward incompatible changes may be added without bumping the major
|
||||
* version of the extension.
|
||||
* @section page_iface_kde_output_device_v2_api API
|
||||
* See @ref iface_kde_output_device_v2.
|
||||
*/
|
||||
@@ -75,6 +80,11 @@ struct kde_output_device_v2;
|
||||
* This object is published as global during start up for every available
|
||||
* display devices, or when one later becomes available, for example by
|
||||
* being hotplugged via a physical connector.
|
||||
*
|
||||
* Warning! The protocol described in this file is a desktop environment
|
||||
* implementation detail. Regular clients must not use this protocol.
|
||||
* Backward incompatible changes may be added without bumping the major
|
||||
* version of the extension.
|
||||
*/
|
||||
extern const struct wl_interface kde_output_device_v2_interface;
|
||||
#endif
|
||||
@@ -199,6 +209,11 @@ enum kde_output_device_v2_capability {
|
||||
* @since 5
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE = 0x40,
|
||||
/**
|
||||
* if this outputdevice supports the brightness setting
|
||||
* @since 9
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_BRIGHTNESS = 0x80,
|
||||
};
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
@@ -216,6 +231,10 @@ enum kde_output_device_v2_capability {
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE_SINCE_VERSION 5
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_BRIGHTNESS_SINCE_VERSION 9
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM
|
||||
@@ -274,6 +293,29 @@ enum kde_output_device_v2_color_profile_source {
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* tradeoff between power and accuracy
|
||||
*
|
||||
* The compositor can do a lot of things that trade between
|
||||
* performance, power and color accuracy. This setting describes
|
||||
* a high level preference from the user about in which direction
|
||||
* that tradeoff should be made.
|
||||
*/
|
||||
enum kde_output_device_v2_color_power_tradeoff {
|
||||
/**
|
||||
* prefer efficiency and performance
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_EFFICIENCY = 0,
|
||||
/**
|
||||
* prefer accuracy
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ACCURACY = 1,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* @struct kde_output_device_v2_listener
|
||||
@@ -593,6 +635,29 @@ struct kde_output_device_v2_listener {
|
||||
void (*brightness)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t brightness);
|
||||
/**
|
||||
* the preferred color/power tradeoff
|
||||
*
|
||||
*
|
||||
* @since 10
|
||||
*/
|
||||
void (*color_power_tradeoff)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t preference);
|
||||
/**
|
||||
* dimming multiplier
|
||||
*
|
||||
* This is the dimming multiplier of the output. This is similar
|
||||
* to the brightness setting, except it's meant to be a temporary
|
||||
* setting only, not persistent and may be implemented differently
|
||||
* depending on the display. 0 is the minimum dimming factor (not
|
||||
* completely dark) and 10000 means the output is not dimmed.
|
||||
* @param multiplier multiplier in 0-10000
|
||||
* @since 11
|
||||
*/
|
||||
void (*dimming)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t multiplier);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -706,34 +771,42 @@ kde_output_device_v2_add_listener(struct kde_output_device_v2 *kde_output_device
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_SINCE_VERSION 8
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_SINCE_VERSION 10
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_DIMMING_SINCE_VERSION 11
|
||||
|
||||
|
||||
// /** @ingroup iface_kde_output_device_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data);
|
||||
// }
|
||||
/** @ingroup iface_kde_output_device_v2 */
|
||||
static inline void
|
||||
kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data);
|
||||
}
|
||||
|
||||
// /** @ingroup iface_kde_output_device_v2 */
|
||||
// static inline void *
|
||||
// kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2);
|
||||
// }
|
||||
/** @ingroup iface_kde_output_device_v2 */
|
||||
static inline void *
|
||||
kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2);
|
||||
}
|
||||
|
||||
// static inline uint32_t
|
||||
// kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2);
|
||||
// }
|
||||
static inline uint32_t
|
||||
kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2);
|
||||
}
|
||||
|
||||
// /** @ingroup iface_kde_output_device_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
// {
|
||||
// wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2);
|
||||
// }
|
||||
/** @ingroup iface_kde_output_device_v2 */
|
||||
static inline void
|
||||
kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
@@ -811,32 +884,32 @@ kde_output_device_mode_v2_add_listener(struct kde_output_device_mode_v2 *kde_out
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1
|
||||
|
||||
|
||||
// /** @ingroup iface_kde_output_device_mode_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data);
|
||||
// }
|
||||
/** @ingroup iface_kde_output_device_mode_v2 */
|
||||
static inline void
|
||||
kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data);
|
||||
}
|
||||
|
||||
// /** @ingroup iface_kde_output_device_mode_v2 */
|
||||
// static inline void *
|
||||
// kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
// }
|
||||
/** @ingroup iface_kde_output_device_mode_v2 */
|
||||
static inline void *
|
||||
kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
}
|
||||
|
||||
// static inline uint32_t
|
||||
// kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
// }
|
||||
static inline uint32_t
|
||||
kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
}
|
||||
|
||||
// /** @ingroup iface_kde_output_device_mode_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
// {
|
||||
// wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
// }
|
||||
/** @ingroup iface_kde_output_device_mode_v2 */
|
||||
static inline void
|
||||
kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifdef FF_HAVE_WAYLAND
|
||||
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
/* Generated by wayland-scanner 1.23.1 */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
|
||||
@@ -12,6 +12,7 @@
|
||||
* SPDX-License-Identifier: MIT-CMU
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <wayland-util.h>
|
||||
@@ -57,12 +58,14 @@ static const struct wl_message kde_output_device_v2_events[] = {
|
||||
{ "sdr_gamut_wideness", "6u", kde_output_device_v2_types + 0 },
|
||||
{ "color_profile_source", "7u", kde_output_device_v2_types + 0 },
|
||||
{ "brightness", "8u", kde_output_device_v2_types + 0 },
|
||||
{ "color_power_tradeoff", "10u", kde_output_device_v2_types + 0 },
|
||||
{ "dimming", "11u", kde_output_device_v2_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface kde_output_device_v2_interface = {
|
||||
"kde_output_device_v2", 8,
|
||||
"kde_output_device_v2", 11,
|
||||
0, NULL,
|
||||
25, kde_output_device_v2_events,
|
||||
27, kde_output_device_v2_events,
|
||||
};
|
||||
|
||||
static const struct wl_message kde_output_device_mode_v2_events[] = {
|
||||
|
||||
@@ -126,10 +126,7 @@ static void waylandKdeNameListener(void* data, FF_MAYBE_UNUSED struct kde_output
|
||||
WaylandDisplay* display = data;
|
||||
display->type = ffdsGetDisplayType(name);
|
||||
// As display->id is used as an internal identifier, we don't need it to be NUL terminated
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
strncpy((char*) &display->id, name, sizeof(display->id));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
ffStrbufAppendS(&display->name, name);
|
||||
}
|
||||
@@ -166,13 +163,15 @@ static struct kde_output_device_v2_listener outputListener = {
|
||||
.sdr_gamut_wideness = (void*) stubListener,
|
||||
.color_profile_source = (void*) stubListener,
|
||||
.brightness = (void*) stubListener,
|
||||
.color_power_tradeoff = (void*) stubListener,
|
||||
.dimming = (void*) stubListener,
|
||||
};
|
||||
|
||||
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_device_v2_interface, version, name, kde_output_device_v2_interface.name, version, NULL);
|
||||
if(output == NULL)
|
||||
return;
|
||||
return "Failed to create kde_output_device_v2";
|
||||
|
||||
FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandKdeMode));
|
||||
WaylandDisplay display = {
|
||||
@@ -186,12 +185,21 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
|
||||
.internal = &modes,
|
||||
};
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to add listener to kde_output_device_v2";
|
||||
}
|
||||
|
||||
if (wldata->ffwl_display_roundtrip(wldata->display) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to roundtrip kde_output_device_v2";
|
||||
}
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
|
||||
if(display.width <= 0 || display.height <= 0 || !display.internal)
|
||||
return;
|
||||
return "Failed to get display information from kde_output_device_v2";
|
||||
|
||||
uint32_t rotation = ffWaylandHandleRotation(&display);
|
||||
|
||||
@@ -234,6 +242,8 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
|
||||
ffStrbufDestroy(&display.description);
|
||||
ffStrbufDestroy(&display.name);
|
||||
ffStrbufDestroy(&display.edidName);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -244,20 +254,30 @@ static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde
|
||||
*id = ffWaylandGenerateIdFromName(output_name);
|
||||
}
|
||||
|
||||
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
const char* ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_order_v1_interface, version, name, kde_output_order_v1_interface.name, version, NULL);
|
||||
if(output == NULL)
|
||||
return;
|
||||
return "Failed to create kde_output_order_v1";
|
||||
|
||||
struct kde_output_order_v1_listener orderListener = {
|
||||
.output = waylandKdeOutputOrderListener,
|
||||
.done = (void*) stubListener,
|
||||
};
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to add listener to kde_output_order_v1";
|
||||
}
|
||||
if (wldata->ffwl_display_roundtrip(wldata->display) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to roundtrip kde_output_order_v1";
|
||||
}
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,10 +18,18 @@
|
||||
#include "kde-output-order-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#if __FreeBSD__
|
||||
#include <sys/un.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
struct ucred ucred;
|
||||
#if __linux__ || (__FreeBSD__ && !__DragonFly__)
|
||||
|
||||
#if __linux
|
||||
struct ucred ucred = {};
|
||||
socklen_t len = sizeof(ucred);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1 || ucred.pid <= 0)
|
||||
return false;
|
||||
@@ -30,6 +38,19 @@ static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed.
|
||||
if (!ffReadFileBuffer(procPath.chars, &result->wmProcessName))
|
||||
return false;
|
||||
#else
|
||||
struct xucred ucred = {};
|
||||
socklen_t len = sizeof(ucred);
|
||||
if (getsockopt(fd, AF_UNSPEC, LOCAL_PEERCRED, &ucred, &len) == -1 || ucred.cr_pid <= 0)
|
||||
return false;
|
||||
|
||||
size_t size = 4096;
|
||||
ffStrbufEnsureFixedLengthFree(&result->wmProcessName, (uint32_t) size);
|
||||
|
||||
if(sysctl((int[]){CTL_KERN, KERN_PROC, KERN_PROC_ARGS, ucred.cr_pid}, 4, result->wmProcessName.chars, &size, NULL, 0 ) != 0)
|
||||
return false;
|
||||
result->wmProcessName.length = (uint32_t) size - 1;
|
||||
#endif
|
||||
|
||||
// #1135: wl-restart is a special case
|
||||
const char* filename = strrchr(result->wmProcessName.chars, '/');
|
||||
@@ -45,14 +66,12 @@ static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_UNUSED(fd, result);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void waylandGlobalAddListener(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
|
||||
{
|
||||
@@ -61,17 +80,20 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
|
||||
if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL) && ffStrEquals(interface, wldata->ffwl_output_interface->name))
|
||||
{
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_GLOBAL;
|
||||
ffWaylandHandleGlobalOutput(wldata, registry, name, version);
|
||||
if (ffWaylandHandleGlobalOutput(wldata, registry, name, version) != NULL)
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_NONE;
|
||||
}
|
||||
else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_ZWLR) && ffStrEquals(interface, zwlr_output_manager_v1_interface.name))
|
||||
{
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_ZWLR;
|
||||
ffWaylandHandleZwlrOutput(wldata, registry, name, version);
|
||||
if (ffWaylandHandleZwlrOutput(wldata, registry, name, version) != NULL)
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_NONE;
|
||||
}
|
||||
else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_KDE) && ffStrEquals(interface, kde_output_device_v2_interface.name))
|
||||
{
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE;
|
||||
ffWaylandHandleKdeOutput(wldata, registry, name, version);
|
||||
if (ffWaylandHandleKdeOutput(wldata, registry, name, version) != NULL)
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_NONE;
|
||||
}
|
||||
else if(ffStrEquals(interface, kde_output_order_v1_interface.name))
|
||||
{
|
||||
@@ -83,7 +105,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
|
||||
}
|
||||
}
|
||||
|
||||
static bool matchDrmConnector(const char* connName, WaylandDisplay* wldata)
|
||||
static FF_MAYBE_UNUSED bool matchDrmConnector(const char* connName, WaylandDisplay* wldata)
|
||||
{
|
||||
// https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_output-event-name
|
||||
// The doc says that "do not assume that the name is a reflection of an underlying DRM connector, X11 connection, etc."
|
||||
@@ -129,8 +151,10 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const
|
||||
if (display->id) return;
|
||||
|
||||
display->type = ffdsGetDisplayType(name);
|
||||
#if __linux__
|
||||
if (!display->edidName.length)
|
||||
matchDrmConnector(name, display);
|
||||
#endif
|
||||
display->id = ffWaylandGenerateIdFromName(name);
|
||||
ffStrbufAppendS(&display->name, name);
|
||||
}
|
||||
|
||||
@@ -79,10 +79,10 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output
|
||||
// Modifies content of display. Don't call this function when calling ffdsAppendDisplay
|
||||
uint32_t ffWaylandHandleRotation(WaylandDisplay* display);
|
||||
|
||||
void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
const char* ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
const char* ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
const char* ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -188,11 +188,11 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
|
||||
wldata->ffwl_proxy_destroy((void*) head);
|
||||
}
|
||||
|
||||
void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
const char* ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zwlr_output_manager_v1_interface, version, name, zwlr_output_manager_v1_interface.name, version, NULL);
|
||||
if(output == NULL)
|
||||
return;
|
||||
return "Failed to bind zwlr_output_manager_v1";
|
||||
|
||||
const struct zwlr_output_manager_v1_listener outputListener = {
|
||||
.head = waylandHandleZwlrHead,
|
||||
@@ -200,9 +200,19 @@ void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry
|
||||
.finished = (void*) stubListener,
|
||||
};
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, wldata);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, wldata) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to add listener to zwlr_output_manager_v1";
|
||||
}
|
||||
if (wldata->ffwl_display_roundtrip(wldata->display) < 0)
|
||||
{
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
return "Failed to roundtrip display";
|
||||
}
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,6 +62,9 @@ static const char* parseEnv(void)
|
||||
if(getenv("HYPRLAND_CMD") != NULL)
|
||||
return "Hyprland";
|
||||
|
||||
if(getenv("SWAYSOCK") != NULL)
|
||||
return "Sway";
|
||||
|
||||
#ifdef __linux__
|
||||
if(
|
||||
getenv("WAYLAND_DISPLAY") != NULL &&
|
||||
@@ -126,8 +129,14 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
|
||||
else if(ffStrEqualsIgnCase(name, "dtwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
|
||||
else if(ffStrEqualsIgnCase(name, "fvwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_FVWM);
|
||||
else if(ffStrEqualsIgnCase(name, "ctwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_CTWM);
|
||||
else if(ffStrEqualsIgnCase(name, "hyprland"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HYPRLAND);
|
||||
else if(ffStrEqualsIgnCase(name, "ratpoison"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_RATPOISON);
|
||||
}
|
||||
|
||||
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
|
||||
@@ -296,10 +305,10 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if(result->dePrettyName.length == 0)
|
||||
applyPrettyNameIfDE(result, proc->p_comm);
|
||||
applyPrettyNameIfDE(result, proc[i].p_comm);
|
||||
|
||||
if(result->wmPrettyName.length == 0)
|
||||
applyNameIfWM(result, proc->p_comm);
|
||||
applyNameIfWM(result, proc[i].p_comm);
|
||||
|
||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||
break;
|
||||
|
||||
@@ -188,7 +188,6 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
ffEdidGetPhysicalSize(edidData, &item->physicalWidth, &item->physicalHeight);
|
||||
}
|
||||
|
||||
return !!item;
|
||||
|
||||
@@ -151,7 +151,6 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
ffEdidGetPhysicalSize(edidData, &item->physicalWidth, &item->physicalHeight);
|
||||
}
|
||||
|
||||
data->ffXRRFreeCrtcInfo(crtcInfo);
|
||||
|
||||
@@ -4,9 +4,15 @@
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#define RESOLV_CONF "/system/settings/network/resolv.conf"
|
||||
#else
|
||||
#define RESOLV_CONF "/etc/resolv.conf"
|
||||
#endif
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf", "r");
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT RESOLV_CONF, "r");
|
||||
if (!file)
|
||||
return "fopen (" FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf) failed";
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ typedef struct FFFontResult
|
||||
* Linux / BSD: Qt, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, System Mono, User Mono
|
||||
* Windows: Caption, Menu, Message, Status
|
||||
* Haiku: Plain, Menu, Bold, Mono
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
*/
|
||||
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
extern "C" {
|
||||
#include "common/font.h"
|
||||
#include "common/parsing.h"
|
||||
#include "font.h"
|
||||
}
|
||||
|
||||
#include <Application.h>
|
||||
#include <Font.h>
|
||||
#include <Menu.h>
|
||||
|
||||
extern "C" {
|
||||
const char* ffDetectFontImpl(FFFontResult* result);
|
||||
}
|
||||
|
||||
static void generateString(FFFontResult* font)
|
||||
{
|
||||
const char* types[] = { "Plain", "Menu", "Bold", "Mono" };
|
||||
for(uint32_t i = 0; i < ARRAY_SIZE(types); ++i)
|
||||
{
|
||||
if(i == 0 || !ffStrbufEqual(&font->fonts[i - 1], &font->fonts[i]))
|
||||
{
|
||||
if(i > 0)
|
||||
ffStrbufAppendS(&font->display, "], ");
|
||||
ffStrbufAppendF(&font->display, "%s [%s", font->fonts[i].chars, types[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&font->display, " / ");
|
||||
ffStrbufAppendS(&font->display, types[i]);
|
||||
}
|
||||
}
|
||||
ffStrbufAppendC(&font->display, ']');
|
||||
}
|
||||
|
||||
const char* ffDetectFontImpl(FFFontResult* result)
|
||||
{
|
||||
struct menu_info menuInfo;
|
||||
const BFont *f;
|
||||
// We need a valid be_app to query the app_server here.
|
||||
BApplication app("application/x-vnd.fastfetch-cli-fastfetch");
|
||||
|
||||
if ((f = be_plain_font) != NULL)
|
||||
{
|
||||
f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style);
|
||||
ffStrbufAppendF(&result->fonts[0], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size());
|
||||
}
|
||||
if (get_menu_info(&menuInfo) == B_OK)
|
||||
{
|
||||
ffStrbufAppendF(&result->fonts[1], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)menuInfo.font_size);
|
||||
}
|
||||
if ((f = be_bold_font) != NULL)
|
||||
{
|
||||
f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style);
|
||||
ffStrbufAppendF(&result->fonts[2], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size());
|
||||
}
|
||||
if ((f = be_fixed_font) != NULL)
|
||||
{
|
||||
f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style);
|
||||
ffStrbufAppendF(&result->fonts[3], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size());
|
||||
}
|
||||
|
||||
generateString(result);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
|
||||
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
|
||||
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
|
||||
|
||||
const char* ffGetGPUVendorString(unsigned vendorId)
|
||||
const char* ffGPUGetVendorString(unsigned vendorId)
|
||||
{
|
||||
// https://devicehunt.com/all-pci-vendors
|
||||
switch (vendorId)
|
||||
@@ -51,9 +51,9 @@ const char* detectByOpenGL(FFlist* gpus)
|
||||
{
|
||||
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInitMove(&gpu->vendor, &result.vendor);
|
||||
ffStrbufInitMove(&gpu->name, &result.renderer);
|
||||
ffStrbufInitMove(&gpu->driver, &result.vendor);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
|
||||
@@ -46,7 +46,7 @@ typedef struct FFGPUResult
|
||||
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
|
||||
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
|
||||
|
||||
const char* ffGetGPUVendorString(unsigned vendorId);
|
||||
const char* ffGPUGetVendorString(unsigned vendorId);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
|
||||
|
||||
@@ -21,6 +21,7 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
case 1: error = ffDetectSmcTemps(FF_TEMP_GPU_M1X, &result); break;
|
||||
case 2: error = ffDetectSmcTemps(FF_TEMP_GPU_M2X, &result); break;
|
||||
case 3: error = ffDetectSmcTemps(FF_TEMP_GPU_M3X, &result); break;
|
||||
case 4: error = ffDetectSmcTemps(FF_TEMP_GPU_M4X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon GPU";
|
||||
}
|
||||
}
|
||||
@@ -161,7 +162,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
int vendorId;
|
||||
if(ffCfDictGetInt(properties, CFSTR("vendor-id"), &vendorId) == NULL)
|
||||
{
|
||||
const char* vendorStr = ffGetGPUVendorString((unsigned) vendorId);
|
||||
const char* vendorStr = ffGPUGetVendorString((unsigned) vendorId);
|
||||
ffStrbufAppendS(&gpu->vendor, vendorStr);
|
||||
if (vendorStr == FF_GPU_VENDOR_NAME_APPLE || vendorStr == FF_GPU_VENDOR_NAME_INTEL)
|
||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
||||
|
||||
@@ -68,6 +68,9 @@ const char* ffGpuDetectMetal(FFlist* gpus)
|
||||
gpu->type = device.location == MTLDeviceLocationBuiltIn ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
gpu->index = (uint32_t) device.locationNumber;
|
||||
#endif
|
||||
|
||||
if (device.hasUnifiedMemory && device.recommendedMaxWorkingSetSize > 0)
|
||||
gpu->shared.total = device.recommendedMaxWorkingSetSize;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
struct pci_conf* pc = &confs[i];
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(pc->pc_vendor));
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(pc->pc_vendor));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInitS(&gpu->driver, pc->pd_name);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
|
||||
@@ -15,7 +15,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pciaccess, pci_slot_match_iterator_create)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pciaccess, pci_device_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pciaccess, pci_system_cleanup)
|
||||
|
||||
|
||||
{
|
||||
// Requires root access
|
||||
// Same behavior can be observed with `cp $(which scanpci) /tmp/ && /tmp/scanpci`
|
||||
@@ -31,7 +31,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
continue;
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(dev->vendor_id));
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(dev->vendor_id));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
|
||||
@@ -435,7 +435,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
return "Invalid PCI device path";
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString((uint16_t) vendorId));
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString((uint16_t) vendorId));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
|
||||
@@ -10,6 +10,7 @@ struct FFNvmlData {
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetPciInfo_v3)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetTemperature)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxClockInfo)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates)
|
||||
@@ -36,6 +37,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetPciInfo_v3)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetTemperature)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxClockInfo)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetUtilizationRates)
|
||||
@@ -130,6 +132,15 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
result.memory->total = memory.used + memory.free;
|
||||
result.memory->used = memory.used;
|
||||
}
|
||||
else
|
||||
{
|
||||
nvmlMemory_t memory_v1;
|
||||
if (nvmlData.ffnvmlDeviceGetMemoryInfo(device, &memory_v1) == NVML_SUCCESS)
|
||||
{
|
||||
result.memory->total = memory_v1.total;
|
||||
result.memory->used = memory_v1.used;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.coreCount)
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef __FreeBSD__
|
||||
#include <paths.h>
|
||||
#include <paths.h>
|
||||
#ifndef _PATH_LOCALBASE
|
||||
#define _PATH_LOCALBASE "/usr/local"
|
||||
#endif
|
||||
#elif __OpenBSD__
|
||||
#define _PATH_LOCALBASE "/usr/local"
|
||||
#elif __NetBSD__
|
||||
#define _PATH_LOCALBASE "/usr/pkg"
|
||||
#endif
|
||||
|
||||
#if FF_HAVE_EMBEDDED_PCIIDS
|
||||
@@ -37,17 +41,10 @@ static const FFstrbuf* loadPciIds()
|
||||
if (pciids.length == 0)
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", &pciids);
|
||||
}
|
||||
#elif __FreeBSD__
|
||||
// https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pciconf/pathnames.h
|
||||
#elif __FreeBSD__ || __OpenBSD__ || __NetBSD__
|
||||
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", &pciids);
|
||||
if (pciids.length == 0)
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/pciids/pci.ids", &pciids);
|
||||
#elif __sun
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
|
||||
#elif __OpenBSD__
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/local/share/pci.ids", &pciids);
|
||||
#elif __NetBSD__
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/pkg/share/pciutils/pci.ids", &pciids);
|
||||
#endif
|
||||
|
||||
#endif // FF_CUSTOM_PCI_IDS_PATH
|
||||
|
||||
@@ -51,7 +51,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
uint32_t revision = (uint32_t) strtoul(pclass, NULL, 16);
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
|
||||
@@ -72,7 +72,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
{
|
||||
uint32_t vendorId = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
|
||||
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
@@ -147,7 +147,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_HARDWAREID, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
|
||||
{
|
||||
swscanf(buffer, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId);
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
|
||||
}
|
||||
|
||||
detectFn(
|
||||
|
||||
@@ -104,7 +104,7 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
||||
DXCoreHardwareID hardwareId;
|
||||
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::HardwareID, sizeof(hardwareId), &hardwareId)))
|
||||
{
|
||||
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
|
||||
const char* vendorStr = ffGPUGetVendorString((unsigned) hardwareId.vendorID);
|
||||
ffStrbufSetStatic(&gpu->vendor, vendorStr);
|
||||
|
||||
if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && (options->driverSpecific || options->temp))
|
||||
|
||||
@@ -56,6 +56,18 @@ typedef struct {
|
||||
// https://github.com/NVIDIA/nvidia-settings/issues/78#issuecomment-1012837988
|
||||
enum { nvmlMemory_v2 = (unsigned int)(sizeof(nvmlMemory_v2_t) | (2 << 24U)) };
|
||||
|
||||
// https://docs.nvidia.com/deploy/nvml-api/structnvmlMemory__t.html#structnvmlMemory__t
|
||||
// Memory allocation information for a device (v1)
|
||||
typedef struct
|
||||
{
|
||||
// Total physical device memory (in bytes)
|
||||
unsigned long long total;
|
||||
// Unallocated device memory (in bytes)
|
||||
unsigned long long free;
|
||||
// Sum of Reserved and Allocated device memory (in bytes)
|
||||
unsigned long long used;
|
||||
} nvmlMemory_t;
|
||||
|
||||
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64
|
||||
// Clock types
|
||||
typedef enum {
|
||||
@@ -124,6 +136,8 @@ extern nvmlReturn_t nvmlDeviceGetPciInfo_v3(nvmlDevice_t device, nvmlPciInfo_t*
|
||||
extern nvmlReturn_t nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int* temp);
|
||||
// Retrieves the amount of used, free, reserved and total memory available on the device, in bytes. The reserved amount is supported on version 2 only
|
||||
extern nvmlReturn_t nvmlDeviceGetMemoryInfo_v2(nvmlDevice_t device, nvmlMemory_v2_t* memory);
|
||||
// Retrieves the amount of used, free, total memory available on the device, in bytes.
|
||||
extern nvmlReturn_t nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t *memory);
|
||||
// Gets the device's core count
|
||||
extern nvmlReturn_t nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* numCores);
|
||||
// Retrieves the maximum clock speeds for the device
|
||||
|
||||
@@ -74,8 +74,7 @@ static bool detectPlasmaFromFile(const char* filename, FFQtResult* result)
|
||||
}
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
free(line);
|
||||
|
||||
fclose(kdeglobals);
|
||||
|
||||
|
||||
@@ -13,4 +13,8 @@ typedef struct FFHostResult
|
||||
FFstrbuf vendor;
|
||||
} FFHostResult;
|
||||
|
||||
const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel);
|
||||
#ifdef __x86_64__
|
||||
bool ffHostDetectMac(FFHostResult* host);
|
||||
#endif
|
||||
const char* ffDetectHost(FFHostResult* host);
|
||||
|
||||
@@ -5,179 +5,6 @@
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
static const char* getProductNameWithHwModel(const FFstrbuf* hwModel)
|
||||
{
|
||||
// Macbook Pro: https://support.apple.com/en-us/HT201300
|
||||
// Macbook Air: https://support.apple.com/en-us/HT201862
|
||||
// Mac mini: https://support.apple.com/en-us/HT201894
|
||||
// iMac: https://support.apple.com/en-us/HT201634
|
||||
// Mac Pro: https://support.apple.com/en-us/HT202888
|
||||
// Mac Studio: https://support.apple.com/en-us/HT213073
|
||||
|
||||
if(ffStrbufStartsWithS(hwModel, "MacBookPro"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBookPro");
|
||||
if(ffStrEquals(version, "18,3") ||
|
||||
ffStrEquals(version, "18,4")) return "MacBook Pro (14-inch, 2021)";
|
||||
if(ffStrEquals(version, "18,1") ||
|
||||
ffStrEquals(version, "18,2")) return "MacBook Pro (16-inch, 2021)";
|
||||
if(ffStrEquals(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)";
|
||||
if(ffStrEquals(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "16,4") ||
|
||||
ffStrEquals(version, "16,1")) return "MacBook Pro (16-inch, 2019)";
|
||||
if(ffStrEquals(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "15,3")) return "MacBook Pro (15-inch, 2019)";
|
||||
if(ffStrEquals(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "15,1")) return "MacBook Pro (15-inch, 2018/2019)";
|
||||
if(ffStrEquals(version, "14,3")) return "MacBook Pro (15-inch, 2017)";
|
||||
if(ffStrEquals(version, "14,2")) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "14,1")) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "13,3")) return "MacBook Pro (15-inch, 2016)";
|
||||
if(ffStrEquals(version, "13,2")) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "13,1")) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "12,1")) return "MacBook Pro (Retina, 13-inch, Early 2015)";
|
||||
if(ffStrEquals(version, "11,4") ||
|
||||
ffStrEquals(version, "11,5")) return "MacBook Pro (Retina, 15-inch, Mid 2015)";
|
||||
if(ffStrEquals(version, "11,2") ||
|
||||
ffStrEquals(version, "11,3")) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrEquals(version, "11,1")) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrEquals(version, "10,2")) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
|
||||
if(ffStrEquals(version, "10,1")) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
|
||||
if(ffStrEquals(version, "9,2")) return "MacBook Pro (13-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "9,1")) return "MacBook Pro (15-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "8,3")) return "MacBook Pro (17-inch, 2011)";
|
||||
if(ffStrEquals(version, "8,2")) return "MacBook Pro (15-inch, 2011)";
|
||||
if(ffStrEquals(version, "8,1")) return "MacBook Pro (13-inch, 2011)";
|
||||
if(ffStrEquals(version, "7,1")) return "MacBook Pro (13-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "6,2")) return "MacBook Pro (15-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "6,1")) return "MacBook Pro (17-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "5,5")) return "MacBook Pro (13-inch, Mid 2009)";
|
||||
if(ffStrEquals(version, "5,3")) return "MacBook Pro (15-inch, Mid 2009)";
|
||||
if(ffStrEquals(version, "5,2")) return "MacBook Pro (17-inch, Mid/Early 2009)";
|
||||
if(ffStrEquals(version, "5,1")) return "MacBook Pro (15-inch, Late 2008)";
|
||||
if(ffStrEquals(version, "4,1")) return "MacBook Pro (17/15-inch, Early 2008)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacBookAir"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBookAir");
|
||||
if(ffStrEquals(version, "10,1")) return "MacBook Air (M1, 2020)";
|
||||
if(ffStrEquals(version, "9,1")) return "MacBook Air (Retina, 13-inch, 2020)";
|
||||
if(ffStrEquals(version, "8,2")) return "MacBook Air (Retina, 13-inch, 2019)";
|
||||
if(ffStrEquals(version, "8,1")) return "MacBook Air (Retina, 13-inch, 2018)";
|
||||
if(ffStrEquals(version, "7,2")) return "MacBook Air (13-inch, Early 2015/2017)";
|
||||
if(ffStrEquals(version, "7,1")) return "MacBook Air (11-inch, Early 2015)";
|
||||
if(ffStrEquals(version, "6,2")) return "MacBook Air (13-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrEquals(version, "6,1")) return "MacBook Air (11-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrEquals(version, "5,2")) return "MacBook Air (13-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "5,1")) return "MacBook Air (11-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "4,2")) return "MacBook Air (13-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "4,1")) return "MacBook Air (11-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "3,2")) return "MacBook Air (13-inch, Late 2010)";
|
||||
if(ffStrEquals(version, "3,1")) return "MacBook Air (11-inch, Late 2010)";
|
||||
if(ffStrEquals(version, "2,1")) return "MacBook Air (Mid 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "Macmini"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Macmini");
|
||||
if(ffStrEquals(version, "9,1")) return "Mac mini (M1, 2020)";
|
||||
if(ffStrEquals(version, "8,1")) return "Mac mini (2018)";
|
||||
if(ffStrEquals(version, "7,1")) return "Mac mini (Mid 2014)";
|
||||
if(ffStrEquals(version, "6,1") ||
|
||||
ffStrEquals(version, "6,2")) return "Mac mini (Late 2012)";
|
||||
if(ffStrEquals(version, "5,1") ||
|
||||
ffStrEquals(version, "5,2")) return "Mac mini (Mid 2011)";
|
||||
if(ffStrEquals(version, "4,1")) return "Mac mini (Mid 2010)";
|
||||
if(ffStrEquals(version, "3,1")) return "Mac mini (Early/Late 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacBook"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBook");
|
||||
if(ffStrEquals(version, "10,1")) return "MacBook (Retina, 12-inch, 2017)";
|
||||
if(ffStrEquals(version, "9,1")) return "MacBook (Retina, 12-inch, Early 2016)";
|
||||
if(ffStrEquals(version, "8,1")) return "MacBook (Retina, 12-inch, Early 2015)";
|
||||
if(ffStrEquals(version, "7,1")) return "MacBook (13-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "6,1")) return "MacBook (13-inch, Late 2009)";
|
||||
if(ffStrEquals(version, "5,2")) return "MacBook (13-inch, Early/Mid 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacPro"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacPro");
|
||||
if(ffStrEquals(version, "7,1")) return "Mac Pro (2019)";
|
||||
if(ffStrEquals(version, "6,1")) return "Mac Pro (Late 2013)";
|
||||
if(ffStrEquals(version, "5,1")) return "Mac Pro (Mid 2010 - Mid 2012)";
|
||||
if(ffStrEquals(version, "4,1")) return "Mac Pro (Early 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "Mac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Mac");
|
||||
if(ffStrEquals(version, "16,3")) return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "16,2")) return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "16,1") ||
|
||||
ffStrEquals(version, "16,6") ||
|
||||
ffStrEquals(version, "16,8")) return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "16,7") ||
|
||||
ffStrEquals(version, "16,5")) return "MacBook Pro (16-inch, 2024, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "16,15") ||
|
||||
ffStrEquals(version, "16,10")) return "Mac mini (2024)";
|
||||
if(ffStrEquals(version, "15,13")) return "MacBook Air (15-inch, M3, 2024)";
|
||||
if(ffStrEquals(version, "15,2")) return "MacBook Air (13-inch, M3, 2024)";
|
||||
if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "15,4")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "15,5")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
|
||||
if(ffStrEquals(version, "15,6") ||
|
||||
ffStrEquals(version, "15,8") ||
|
||||
ffStrEquals(version, "15,10")) return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "15,7") ||
|
||||
ffStrEquals(version, "15,9") ||
|
||||
ffStrEquals(version, "15,11")) return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,15")) return "MacBook Air (15-inch, M2, 2023)";
|
||||
if(ffStrEquals(version, "14,14")) return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)";
|
||||
if(ffStrEquals(version, "14,13")) return "Mac Studio (M2 Max, 2023, Two USB-C front ports)";
|
||||
if(ffStrEquals(version, "14,8")) return "Mac Pro (2023)";
|
||||
if(ffStrEquals(version, "14,6") ||
|
||||
ffStrEquals(version, "14,10")) return "MacBook Pro (16-inch, 2023)";
|
||||
if(ffStrEquals(version, "14,5") ||
|
||||
ffStrEquals(version, "14,9")) return "MacBook Pro (14-inch, 2023)";
|
||||
if(ffStrEquals(version, "14,3")) return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,12")) return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,7")) return "MacBook Pro (13-inch, M2, 2022)";
|
||||
if(ffStrEquals(version, "14,2")) return "MacBook Air (M2, 2022)";
|
||||
if(ffStrEquals(version, "13,1")) return "Mac Studio (M1 Max, 2022, Two USB-C front ports)";
|
||||
if(ffStrEquals(version, "13,2")) return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "iMac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("iMac");
|
||||
if(ffStrEquals(version, "21,1")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
|
||||
if(ffStrEquals(version, "21,2")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "20,1") ||
|
||||
ffStrEquals(version, "20,2")) return "iMac (Retina 5K, 27-inch, 2020)";
|
||||
if(ffStrEquals(version, "19,1")) return "iMac (Retina 5K, 27-inch, 2019)";
|
||||
if(ffStrEquals(version, "19,2")) return "iMac (Retina 4K, 21.5-inch, 2019)";
|
||||
if(ffStrEquals(version, "Pro1,1")) return "iMac Pro (2017)";
|
||||
if(ffStrEquals(version, "18,3")) return "iMac (Retina 5K, 27-inch, 2017)";
|
||||
if(ffStrEquals(version, "18,2")) return "iMac (Retina 4K, 21.5-inch, 2017)";
|
||||
if(ffStrEquals(version, "18,1")) return "iMac (21.5-inch, 2017)";
|
||||
if(ffStrEquals(version, "17,1")) return "iMac (Retina 5K, 27-inch, Late 2015)";
|
||||
if(ffStrEquals(version, "16,2")) return "iMac (Retina 4K, 21.5-inch, Late 2015)";
|
||||
if(ffStrEquals(version, "16,1")) return "iMac (21.5-inch, Late 2015)";
|
||||
if(ffStrEquals(version, "15,1")) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
|
||||
if(ffStrEquals(version, "14,4")) return "iMac (21.5-inch, Mid 2014)";
|
||||
if(ffStrEquals(version, "14,2")) return "iMac (27-inch, Late 2013)";
|
||||
if(ffStrEquals(version, "14,1")) return "iMac (21.5-inch, Late 2013)";
|
||||
if(ffStrEquals(version, "13,2")) return "iMac (27-inch, Late 2012)";
|
||||
if(ffStrEquals(version, "13,1")) return "iMac (21.5-inch, Late 2012)";
|
||||
if(ffStrEquals(version, "12,2")) return "iMac (27-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "12,1")) return "iMac (21.5-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "11,3")) return "iMac (27-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "11,2")) return "iMac (21.5-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)";
|
||||
if(ffStrEquals(version, "9,1")) return "iMac (24/20-inch, Early 2009)";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* getProductNameWithIokit(FFstrbuf* result)
|
||||
{
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t registryEntry = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceNameMatching("product"));
|
||||
@@ -217,7 +44,7 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
const char* error = ffSysctlGetString("hw.model", &host->family);
|
||||
if (error) return error;
|
||||
|
||||
ffStrbufSetStatic(&host->name, getProductNameWithHwModel(&host->family));
|
||||
ffStrbufSetStatic(&host->name, ffHostGetMacProductNameWithHwModel(&host->family));
|
||||
if (host->name.length == 0)
|
||||
getProductNameWithIokit(&host->name);
|
||||
if (host->name.length == 0)
|
||||
|
||||
@@ -19,5 +19,9 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
ffSettingsGetFreeBSDKenv("smbios.system.maker", &host->vendor);
|
||||
ffCleanUpSmbiosValue(&host->vendor);
|
||||
|
||||
#ifdef __x86_64__
|
||||
ffHostDetectMac(host);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
ffStrbufSetStatic(&host->vendor, "Apple Inc.");
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
ffHostDetectMac(host);
|
||||
#endif
|
||||
|
||||
//KVM/Qemu virtual machine
|
||||
if(ffStrbufStartsWithS(&host->name, "Standard PC"))
|
||||
ffStrbufPrependS(&host->name, "KVM/QEMU ");
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
#include "host.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel)
|
||||
{
|
||||
// Macbook Pro: https://support.apple.com/en-us/HT201300
|
||||
// Macbook Air: https://support.apple.com/en-us/HT201862
|
||||
// Mac mini: https://support.apple.com/en-us/HT201894
|
||||
// iMac: https://support.apple.com/en-us/HT201634
|
||||
// Mac Pro: https://support.apple.com/en-us/HT202888
|
||||
// Mac Studio: https://support.apple.com/en-us/HT213073
|
||||
|
||||
if(ffStrbufStartsWithS(hwModel, "MacBookPro"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBookPro");
|
||||
if(ffStrEquals(version, "18,3") ||
|
||||
ffStrEquals(version, "18,4")) return "MacBook Pro (14-inch, 2021)";
|
||||
if(ffStrEquals(version, "18,1") ||
|
||||
ffStrEquals(version, "18,2")) return "MacBook Pro (16-inch, 2021)";
|
||||
if(ffStrEquals(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)";
|
||||
if(ffStrEquals(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "16,4") ||
|
||||
ffStrEquals(version, "16,1")) return "MacBook Pro (16-inch, 2019)";
|
||||
if(ffStrEquals(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "15,3")) return "MacBook Pro (15-inch, 2019)";
|
||||
if(ffStrEquals(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "15,1")) return "MacBook Pro (15-inch, 2018/2019)";
|
||||
if(ffStrEquals(version, "14,3")) return "MacBook Pro (15-inch, 2017)";
|
||||
if(ffStrEquals(version, "14,2")) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "14,1")) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "13,3")) return "MacBook Pro (15-inch, 2016)";
|
||||
if(ffStrEquals(version, "13,2")) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "13,1")) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
|
||||
if(ffStrEquals(version, "12,1")) return "MacBook Pro (Retina, 13-inch, Early 2015)";
|
||||
if(ffStrEquals(version, "11,4") ||
|
||||
ffStrEquals(version, "11,5")) return "MacBook Pro (Retina, 15-inch, Mid 2015)";
|
||||
if(ffStrEquals(version, "11,2") ||
|
||||
ffStrEquals(version, "11,3")) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrEquals(version, "11,1")) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrEquals(version, "10,2")) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
|
||||
if(ffStrEquals(version, "10,1")) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
|
||||
if(ffStrEquals(version, "9,2")) return "MacBook Pro (13-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "9,1")) return "MacBook Pro (15-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "8,3")) return "MacBook Pro (17-inch, 2011)";
|
||||
if(ffStrEquals(version, "8,2")) return "MacBook Pro (15-inch, 2011)";
|
||||
if(ffStrEquals(version, "8,1")) return "MacBook Pro (13-inch, 2011)";
|
||||
if(ffStrEquals(version, "7,1")) return "MacBook Pro (13-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "6,2")) return "MacBook Pro (15-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "6,1")) return "MacBook Pro (17-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "5,5")) return "MacBook Pro (13-inch, Mid 2009)";
|
||||
if(ffStrEquals(version, "5,3")) return "MacBook Pro (15-inch, Mid 2009)";
|
||||
if(ffStrEquals(version, "5,2")) return "MacBook Pro (17-inch, Mid/Early 2009)";
|
||||
if(ffStrEquals(version, "5,1")) return "MacBook Pro (15-inch, Late 2008)";
|
||||
if(ffStrEquals(version, "4,1")) return "MacBook Pro (17/15-inch, Early 2008)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacBookAir"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBookAir");
|
||||
if(ffStrEquals(version, "10,1")) return "MacBook Air (M1, 2020)";
|
||||
if(ffStrEquals(version, "9,1")) return "MacBook Air (Retina, 13-inch, 2020)";
|
||||
if(ffStrEquals(version, "8,2")) return "MacBook Air (Retina, 13-inch, 2019)";
|
||||
if(ffStrEquals(version, "8,1")) return "MacBook Air (Retina, 13-inch, 2018)";
|
||||
if(ffStrEquals(version, "7,2")) return "MacBook Air (13-inch, Early 2015/2017)";
|
||||
if(ffStrEquals(version, "7,1")) return "MacBook Air (11-inch, Early 2015)";
|
||||
if(ffStrEquals(version, "6,2")) return "MacBook Air (13-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrEquals(version, "6,1")) return "MacBook Air (11-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrEquals(version, "5,2")) return "MacBook Air (13-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "5,1")) return "MacBook Air (11-inch, Mid 2012)";
|
||||
if(ffStrEquals(version, "4,2")) return "MacBook Air (13-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "4,1")) return "MacBook Air (11-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "3,2")) return "MacBook Air (13-inch, Late 2010)";
|
||||
if(ffStrEquals(version, "3,1")) return "MacBook Air (11-inch, Late 2010)";
|
||||
if(ffStrEquals(version, "2,1")) return "MacBook Air (Mid 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "Macmini"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Macmini");
|
||||
if(ffStrEquals(version, "9,1")) return "Mac mini (M1, 2020)";
|
||||
if(ffStrEquals(version, "8,1")) return "Mac mini (2018)";
|
||||
if(ffStrEquals(version, "7,1")) return "Mac mini (Mid 2014)";
|
||||
if(ffStrEquals(version, "6,1") ||
|
||||
ffStrEquals(version, "6,2")) return "Mac mini (Late 2012)";
|
||||
if(ffStrEquals(version, "5,1") ||
|
||||
ffStrEquals(version, "5,2")) return "Mac mini (Mid 2011)";
|
||||
if(ffStrEquals(version, "4,1")) return "Mac mini (Mid 2010)";
|
||||
if(ffStrEquals(version, "3,1")) return "Mac mini (Early/Late 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacBook"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBook");
|
||||
if(ffStrEquals(version, "10,1")) return "MacBook (Retina, 12-inch, 2017)";
|
||||
if(ffStrEquals(version, "9,1")) return "MacBook (Retina, 12-inch, Early 2016)";
|
||||
if(ffStrEquals(version, "8,1")) return "MacBook (Retina, 12-inch, Early 2015)";
|
||||
if(ffStrEquals(version, "7,1")) return "MacBook (13-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "6,1")) return "MacBook (13-inch, Late 2009)";
|
||||
if(ffStrEquals(version, "5,2")) return "MacBook (13-inch, Early/Mid 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacPro"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacPro");
|
||||
if(ffStrEquals(version, "7,1")) return "Mac Pro (2019)";
|
||||
if(ffStrEquals(version, "6,1")) return "Mac Pro (Late 2013)";
|
||||
if(ffStrEquals(version, "5,1")) return "Mac Pro (Mid 2010 - Mid 2012)";
|
||||
if(ffStrEquals(version, "4,1")) return "Mac Pro (Early 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "Mac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Mac");
|
||||
if(ffStrEquals(version, "16,3")) return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "16,2")) return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "16,1")) return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "16,6") ||
|
||||
ffStrEquals(version, "16,8")) return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)";
|
||||
if(ffStrEquals(version, "16,7") ||
|
||||
ffStrEquals(version, "16,5")) return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)";
|
||||
if(ffStrEquals(version, "16,15") ||
|
||||
ffStrEquals(version, "16,10")) return "Mac mini (2024)";
|
||||
if(ffStrEquals(version, "15,13")) return "MacBook Air (15-inch, M3, 2024)";
|
||||
if(ffStrEquals(version, "15,2")) return "MacBook Air (13-inch, M3, 2024)";
|
||||
if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "15,4")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "15,5")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
|
||||
if(ffStrEquals(version, "15,6") ||
|
||||
ffStrEquals(version, "15,8") ||
|
||||
ffStrEquals(version, "15,10")) return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "15,7") ||
|
||||
ffStrEquals(version, "15,9") ||
|
||||
ffStrEquals(version, "15,11")) return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,15")) return "MacBook Air (15-inch, M2, 2023)";
|
||||
if(ffStrEquals(version, "14,14")) return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)";
|
||||
if(ffStrEquals(version, "14,13")) return "Mac Studio (M2 Max, 2023, Two USB-C front ports)";
|
||||
if(ffStrEquals(version, "14,8")) return "Mac Pro (2023)";
|
||||
if(ffStrEquals(version, "14,6") ||
|
||||
ffStrEquals(version, "14,10")) return "MacBook Pro (16-inch, 2023)";
|
||||
if(ffStrEquals(version, "14,5") ||
|
||||
ffStrEquals(version, "14,9")) return "MacBook Pro (14-inch, 2023)";
|
||||
if(ffStrEquals(version, "14,3")) return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,12")) return "Mac mini (M2, 2023, Four Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,7")) return "MacBook Pro (13-inch, M2, 2022)";
|
||||
if(ffStrEquals(version, "14,2")) return "MacBook Air (M2, 2022)";
|
||||
if(ffStrEquals(version, "13,1")) return "Mac Studio (M1 Max, 2022, Two USB-C front ports)";
|
||||
if(ffStrEquals(version, "13,2")) return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "iMac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("iMac");
|
||||
if(ffStrEquals(version, "21,1")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
|
||||
if(ffStrEquals(version, "21,2")) return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "20,1") ||
|
||||
ffStrEquals(version, "20,2")) return "iMac (Retina 5K, 27-inch, 2020)";
|
||||
if(ffStrEquals(version, "19,1")) return "iMac (Retina 5K, 27-inch, 2019)";
|
||||
if(ffStrEquals(version, "19,2")) return "iMac (Retina 4K, 21.5-inch, 2019)";
|
||||
if(ffStrEquals(version, "Pro1,1")) return "iMac Pro (2017)";
|
||||
if(ffStrEquals(version, "18,3")) return "iMac (Retina 5K, 27-inch, 2017)";
|
||||
if(ffStrEquals(version, "18,2")) return "iMac (Retina 4K, 21.5-inch, 2017)";
|
||||
if(ffStrEquals(version, "18,1")) return "iMac (21.5-inch, 2017)";
|
||||
if(ffStrEquals(version, "17,1")) return "iMac (Retina 5K, 27-inch, Late 2015)";
|
||||
if(ffStrEquals(version, "16,2")) return "iMac (Retina 4K, 21.5-inch, Late 2015)";
|
||||
if(ffStrEquals(version, "16,1")) return "iMac (21.5-inch, Late 2015)";
|
||||
if(ffStrEquals(version, "15,1")) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
|
||||
if(ffStrEquals(version, "14,4")) return "iMac (21.5-inch, Mid 2014)";
|
||||
if(ffStrEquals(version, "14,2")) return "iMac (27-inch, Late 2013)";
|
||||
if(ffStrEquals(version, "14,1")) return "iMac (21.5-inch, Late 2013)";
|
||||
if(ffStrEquals(version, "13,2")) return "iMac (27-inch, Late 2012)";
|
||||
if(ffStrEquals(version, "13,1")) return "iMac (21.5-inch, Late 2012)";
|
||||
if(ffStrEquals(version, "12,2")) return "iMac (27-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "12,1")) return "iMac (21.5-inch, Mid 2011)";
|
||||
if(ffStrEquals(version, "11,3")) return "iMac (27-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "11,2")) return "iMac (21.5-inch, Mid 2010)";
|
||||
if(ffStrEquals(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)";
|
||||
if(ffStrEquals(version, "9,1")) return "iMac (24/20-inch, Early 2009)";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
bool ffHostDetectMac(FFHostResult* host)
|
||||
{
|
||||
if (ffStrbufEqualS(&host->family, "Mac") && ffStrbufEqualS(&host->vendor, "Apple Inc."))
|
||||
{
|
||||
const char* productName = ffHostGetMacProductNameWithHwModel(&host->name);
|
||||
if (productName)
|
||||
{
|
||||
ffStrbufDestroy(&host->family);
|
||||
ffStrbufInitMove(&host->family, &host->name);
|
||||
ffStrbufSetStatic(&host->name, productName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -12,6 +12,10 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
ffCleanUpSmbiosValue(&host->vendor);
|
||||
if (ffSysctlGetString("machdep.dmi.system-version", &host->version) == NULL)
|
||||
ffCleanUpSmbiosValue(&host->version);
|
||||
if (ffSysctlGetString("machdep.dmi.system-serial", &host->serial) == NULL)
|
||||
ffCleanUpSmbiosValue(&host->serial);
|
||||
if (ffSysctlGetString("machdep.dmi.system-uuid", &host->uuid) == NULL)
|
||||
ffCleanUpSmbiosValue(&host->uuid);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -72,5 +72,9 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
ffCleanUpSmbiosValue(&host->family);
|
||||
}
|
||||
|
||||
#if _WIN32 && __x86_64__
|
||||
ffHostDetectMac(host);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,23 +18,27 @@
|
||||
#include <linux/if.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__HAIKU__)
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
#endif
|
||||
#ifdef __sun
|
||||
#if defined(__sun) || defined(__HAIKU__)
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
static const FFLocalIpNIFlag niFlagOptions[] = {
|
||||
{ IFF_UP, "UP" },
|
||||
{ IFF_BROADCAST, "BROADCAST" },
|
||||
#ifdef IFF_DEBUG
|
||||
{ IFF_DEBUG, "DEBUG" },
|
||||
#endif
|
||||
{ IFF_LOOPBACK, "LOOPBACK" },
|
||||
{ IFF_POINTOPOINT, "POINTOPOINT" },
|
||||
#ifdef IFF_RUNNING
|
||||
{ IFF_RUNNING, "RUNNING" },
|
||||
#endif
|
||||
{ IFF_NOARP, "NOARP" },
|
||||
{ IFF_PROMISC, "PROMISC" },
|
||||
{ IFF_ALLMULTI, "ALLMULTI" },
|
||||
@@ -64,6 +68,13 @@ static const FFLocalIpNIFlag niFlagOptions[] = {
|
||||
#endif
|
||||
#ifdef IFF_CANTCONFIG
|
||||
{ IFF_CANTCONFIG, "CANTCONFIG" },
|
||||
#endif
|
||||
#ifdef __HAIKU__
|
||||
{ IFF_AUTOUP, "IAUTOUP" },
|
||||
{ IFF_SIMPLEX, "SIMPLEX" },
|
||||
{ IFF_LINK, "LINK" },
|
||||
{ IFF_AUTO_CONFIGURED, "AUTO_CONFIGURED" },
|
||||
{ IFF_CONFIGURING, "CONFIGURING" },
|
||||
#endif
|
||||
// sentinel
|
||||
{},
|
||||
@@ -128,8 +139,12 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
|
||||
for (struct ifaddrs* ifa = ifAddrStruct; ifa; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING))
|
||||
if (!ifa->ifa_addr)
|
||||
continue;
|
||||
#ifdef IFF_RUNNING
|
||||
if (!(ifa->ifa_flags & IFF_RUNNING))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
bool isDefaultRoute = ffStrEquals(defaultRouteIfName, ifa->ifa_name);
|
||||
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
|
||||
@@ -190,7 +205,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
|
||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
|
||||
}
|
||||
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__
|
||||
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ || __HAIKU__
|
||||
else if (ifa->ifa_addr->sa_family == AF_LINK)
|
||||
{
|
||||
if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT))
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include "common/dbus.h"
|
||||
#include "common/library.h"
|
||||
|
||||
#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \
|
||||
{ \
|
||||
@@ -78,7 +77,7 @@ static bool parseMprisMetadata(FFDBusData* data, DBusMessageIter* rootIterator,
|
||||
static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResult* result)
|
||||
{
|
||||
// Get all properties at once to reduce the number of IPCs
|
||||
DBusMessage* reply = ffDBusGetAllProperties(data, busName, "/org/mpris/MediaPlayer2", "");
|
||||
DBusMessage* reply = ffDBusGetAllProperties(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player");
|
||||
if(reply == NULL)
|
||||
return false;
|
||||
|
||||
@@ -93,8 +92,6 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul
|
||||
DBusMessageIter arrayIterator;
|
||||
data->lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY desktopIdentity = ffStrbufCreate();
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY)
|
||||
@@ -112,35 +109,61 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul
|
||||
parseMprisMetadata(data, &dictIterator, result);
|
||||
else if(ffStrEquals(key, "PlaybackStatus"))
|
||||
ffDBusGetString(data, &dictIterator, &result->status);
|
||||
else if(ffStrEquals(key, "Identity"))
|
||||
ffDBusGetString(data, &dictIterator, &result->player);
|
||||
else if(ffStrEquals(key, "DesktopEntry"))
|
||||
ffDBusGetString(data, &dictIterator, &desktopIdentity);
|
||||
|
||||
FF_DBUS_ITER_CONTINUE(data, &arrayIterator)
|
||||
}
|
||||
|
||||
if(result->song.length == 0)
|
||||
{
|
||||
ffStrbufClear(&result->artist);
|
||||
ffStrbufClear(&result->album);
|
||||
ffStrbufClear(&result->url);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result->player.length == 0)
|
||||
{
|
||||
if (desktopIdentity.length > 0)
|
||||
if(result->url.length)
|
||||
{
|
||||
ffStrbufDestroy(&result->player);
|
||||
ffStrbufInitMove(&result->player, &desktopIdentity);
|
||||
const char* fileName = memrchr(result->url.chars, '/', result->url.length);
|
||||
assert(fileName);
|
||||
++fileName;
|
||||
ffStrbufEnsureFixedLengthFree(&result->song, result->url.length - (uint32_t) (fileName - result->url.chars));
|
||||
for(; *fileName && *fileName != '?'; ++fileName)
|
||||
{
|
||||
if (*fileName != '%')
|
||||
{
|
||||
ffStrbufAppendC(&result->song, *fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[] = { fileName[1], fileName[2], 0 };
|
||||
if (str[0] == 0 || str[1] == 0)
|
||||
break;
|
||||
ffStrbufAppendC(&result->song, (char) strtoul(str, NULL, 16));
|
||||
fileName += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppend(&result->player, &result->playerId);
|
||||
ffStrbufClear(&result->artist);
|
||||
ffStrbufClear(&result->album);
|
||||
ffStrbufClear(&result->url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Set short bus name
|
||||
ffStrbufAppendS(&result->playerId, busName + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
|
||||
//We found a song, get the player name
|
||||
if (ffStrbufStartsWithS(&result->playerId, "musikcube.instance"))
|
||||
{
|
||||
// dbus calls are EXTREMELY slow on musikcube, so we set the player name manually
|
||||
ffStrbufSetStatic(&result->player, "musikcube");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Identity", &result->player);
|
||||
if(result->player.length == 0)
|
||||
ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "DesktopEntry", &result->player);
|
||||
if(result->player.length == 0)
|
||||
ffStrbufAppend(&result->player, &result->playerId);
|
||||
}
|
||||
|
||||
data->lib->ffdbus_message_unref(reply);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -4,13 +4,7 @@
|
||||
const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
{
|
||||
size_t length = sizeof(ram->bytesTotal);
|
||||
if (sysctl((int[]){ CTL_HW,
|
||||
#if __NetBSD__
|
||||
HW_PHYSMEM64
|
||||
#else
|
||||
HW_PHYSMEM
|
||||
#endif
|
||||
}, 2, &ram->bytesTotal, &length, NULL, 0))
|
||||
if (sysctl((int[]){ CTL_HW, HW_PHYSMEM }, 2, &ram->bytesTotal, &length, NULL, 0))
|
||||
return "Failed to read hw.physmem";
|
||||
|
||||
// vm.stats.vm.* are int values
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "memory.h"
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
{
|
||||
system_info info;
|
||||
if (get_system_info(&info) != B_OK)
|
||||
return "Error getting system info";
|
||||
|
||||
ram->bytesTotal = B_PAGE_SIZE * info.max_pages;
|
||||
ram->bytesUsed = B_PAGE_SIZE * info.used_pages;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "memory.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
{
|
||||
struct uvmexp_sysctl buf;
|
||||
size_t length = sizeof(buf);
|
||||
if (sysctl((int[]){ CTL_VM, VM_UVMEXP2 }, 2, &buf, &length, NULL, 0) < 0)
|
||||
return "sysctl(CTL_VM, VM_UVMEXP2) failed";
|
||||
|
||||
ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize;
|
||||
ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2,10 +2,7 @@
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#if __NetBSD__
|
||||
#include <uvm/uvm_extern.h>
|
||||
#endif
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
{
|
||||
@@ -15,7 +12,7 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
return "sysctl(CTL_VM, VM_UVMEXP) failed";
|
||||
|
||||
ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize;
|
||||
ram->bytesUsed = ram->bytesTotal - (uint64_t) buf.free * instance.state.platform.sysinfo.pageSize;
|
||||
ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
|
||||
{
|
||||
cl_uint vendorId;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR_ID, sizeof(vendorId), &vendorId, NULL) == CL_SUCCESS)
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
|
||||
if (gpu->vendor.length == 0 && data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
|
||||
ffStrbufSetS(&gpu->vendor, buffer);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user