mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
197 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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
|
||||
@@ -197,6 +197,42 @@ jobs:
|
||||
name: fastfetch-linux-armv7
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-armv6:
|
||||
name: Linux-armv6
|
||||
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
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-armv6
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-riscv64:
|
||||
name: Linux-riscv64
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -232,6 +268,41 @@ 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
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-ppc64le
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
musl-amd64:
|
||||
name: Musl-amd64
|
||||
runs-on: ubuntu-latest
|
||||
@@ -377,7 +448,7 @@ jobs:
|
||||
architecture: x86-64
|
||||
cpu_count: 4
|
||||
shell: bash
|
||||
version: '14.1'
|
||||
version: '14.2'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
@@ -449,10 +520,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
|
||||
@@ -577,7 +648,9 @@ jobs:
|
||||
- linux-amd64
|
||||
- linux-aarch64
|
||||
- linux-armv7
|
||||
- linux-armv6
|
||||
- linux-riscv64
|
||||
- linux-ppc64le
|
||||
- musl-amd64
|
||||
- macos-universal
|
||||
- freebsd-amd64
|
||||
|
||||
+161
@@ -1,3 +1,164 @@
|
||||
# 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:
|
||||
|
||||
+82
-36
@@ -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.35.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -70,8 +70,8 @@ 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" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
@@ -86,6 +86,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,7 +134,7 @@ 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")
|
||||
@@ -502,6 +503,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 +534,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 +617,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 +650,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 +689,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 +706,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 +752,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
|
||||
@@ -777,13 +788,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
|
||||
@@ -881,6 +892,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 +922,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 +961,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 +1003,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
|
||||
)
|
||||
@@ -1128,6 +1142,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)
|
||||
@@ -1216,6 +1238,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 +1489,7 @@ elseif(FreeBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "usbhid"
|
||||
PRIVATE "bluetooth"
|
||||
)
|
||||
if(NOT DragonFly)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1481,6 +1508,7 @@ elseif(OpenBSD)
|
||||
elseif(NetBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "prop"
|
||||
)
|
||||
elseif(SunOS)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1607,41 +1635,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 +1722,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
|
||||
|
||||
@@ -199,10 +199,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
+30
@@ -1,3 +1,33 @@
|
||||
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.34.1_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
|
||||
|
||||
+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);
|
||||
|
||||
+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)
|
||||
|
||||
@@ -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>",
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
+102
-46
@@ -44,12 +44,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 +87,7 @@ static double detectCPUTemp(void)
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
return 0.0/0.0;
|
||||
return detectTZTemp(&buffer);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -89,7 +97,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 +148,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 +195,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 +214,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)
|
||||
{
|
||||
@@ -234,11 +284,14 @@ static const char* parseCpuInfo(
|
||||
{
|
||||
//Stop after reasonable information is acquired
|
||||
if((*line == '\0' || *line == '\n')
|
||||
#if __arm__ || __loongarch__
|
||||
#if __arm__ || __aarch64__ || __loongarch__
|
||||
&& cpu->name.length > 0 // #1202 #1204
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ffStrbufGetlineRestore(&line, &len, cpuinfo);
|
||||
break;
|
||||
}
|
||||
|
||||
(void)(
|
||||
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
|
||||
@@ -383,7 +436,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;
|
||||
@@ -507,6 +560,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
|
||||
#if __x86_64__ || __i386__
|
||||
cpu->packages = getPackageCount(&cpuinfo);
|
||||
if (cpu->packages > 1)
|
||||
cpu->coresPhysical *= cpu->packages; // https://github.com/hykilpikonna/hyfetch/issues/374#issuecomment-2571578914
|
||||
#endif
|
||||
|
||||
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
|
||||
@@ -514,35 +569,36 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* 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);
|
||||
}
|
||||
#if __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#elif !(__x86_64__ || __i386__)
|
||||
detectSocName(cpu);
|
||||
#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);
|
||||
#endif
|
||||
|
||||
if (cpu->name.length == 0)
|
||||
detectArmName(&cpuinfo, cpu, cpuImplementer);
|
||||
#elif !(__x86_64__ || __i386__)
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -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,14 +124,22 @@ 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)
|
||||
{
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -161,7 +161,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
#include "fastfetch.h"
|
||||
#include "opengl.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if __ANDROID__ && !defined(FF_HAVE_EGL)
|
||||
// On Android, installing OpenGL headers is enough (mesa-dev)
|
||||
#if __has_include(<EGL/egl.h>)
|
||||
#define FF_HAVE_EGL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FF_HAVE_EGL) || defined(FF_HAVE_GLX) || defined(FF_HAVE_OSMESA)
|
||||
#define FF_HAVE_GL 1
|
||||
|
||||
@@ -140,6 +148,8 @@ static const char* detectByGlx(FFOpenGLResult* result)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCloseDisplay);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XFree);
|
||||
|
||||
FF_SUPPRESS_IO();
|
||||
|
||||
return glxHandleData(result, &data);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#if __has_include(<GL/gl.h>)
|
||||
#include <GL/gl.h>
|
||||
#elif __has_include(<OpenGL/gl.h>)
|
||||
#elif __APPLE__
|
||||
#define GL_SILENCE_DEPRECATION 1
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
@@ -27,7 +27,10 @@ void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglG
|
||||
#if defined(FF_HAVE_EGL) || __has_include(<EGL/egl.h>)
|
||||
#include "common/io/io.h"
|
||||
|
||||
#define EGL_EGL_PROTOTYPES 1
|
||||
#define EGL_EGLEXT_PROTOTYPES 1
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
typedef struct EGLData
|
||||
{
|
||||
@@ -61,9 +64,14 @@ static const char* eglHandleContext(FFOpenGLResult* result, EGLData* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data)
|
||||
static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data, bool gles)
|
||||
{
|
||||
data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){EGL_NONE});
|
||||
data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){
|
||||
EGL_CONTEXT_CLIENT_VERSION, gles ? 2 : 1, // Try GLES 2.0+ first
|
||||
EGL_NONE
|
||||
});
|
||||
if(data->context == EGL_NO_CONTEXT && gles) // Some ANGLE builds support GLES 1.1 only
|
||||
data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){EGL_NONE});
|
||||
if(data->context == EGL_NO_CONTEXT)
|
||||
return "eglCreateContext returned EGL_NO_CONTEXT";
|
||||
|
||||
@@ -75,10 +83,11 @@ static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data)
|
||||
static const char* eglHandleDisplay(FFOpenGLResult* result, EGLData* data)
|
||||
{
|
||||
// try use OpenGL API. If failed, use the default API (usually OpenGL ES)
|
||||
data->ffeglBindAPI(EGL_OPENGL_API);
|
||||
bool gles = !data->ffeglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
EGLint eglConfigCount;
|
||||
data->ffeglGetConfigs(data->display, &data->config, 1, &eglConfigCount);
|
||||
|
||||
if(eglConfigCount == 0)
|
||||
return "eglGetConfigs returned 0 configs";
|
||||
|
||||
@@ -91,7 +100,7 @@ static const char* eglHandleDisplay(FFOpenGLResult* result, EGLData* data)
|
||||
if(data->surface == EGL_NO_SURFACE)
|
||||
return "eglCreatePbufferSurface returned EGL_NO_SURFACE";
|
||||
|
||||
const char* error = eglHandleSurface(result, data);
|
||||
const char* error = eglHandleSurface(result, data, gles);
|
||||
data->ffeglDestroySurface(data->display, data->surface);
|
||||
return error;
|
||||
}
|
||||
@@ -102,9 +111,20 @@ static const char* eglHandleData(FFOpenGLResult* result, EGLData* data)
|
||||
if(!data->ffglGetString)
|
||||
return "eglGetProcAddress(glGetString) returned NULL";
|
||||
|
||||
data->display = data->ffeglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if(data->display == EGL_NO_DISPLAY)
|
||||
return "eglGetDisplay returned EGL_NO_DISPLAY";
|
||||
#if EGL_VERSION_1_5
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC ffeglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYEXTPROC) data->ffeglGetProcAddress("eglGetPlatformDisplay");
|
||||
if (ffeglGetPlatformDisplay)
|
||||
data->display = ffeglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA, NULL, NULL);
|
||||
|
||||
if(!ffeglGetPlatformDisplay || data->display == EGL_NO_DISPLAY)
|
||||
#endif
|
||||
|
||||
{
|
||||
data->display = data->ffeglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if(data->display == EGL_NO_DISPLAY)
|
||||
return "eglGetDisplay returned EGL_NO_DISPLAY";
|
||||
}
|
||||
|
||||
|
||||
EGLint major, minor;
|
||||
if(data->ffeglInitialize(data->display, &major, &minor) == EGL_FALSE)
|
||||
|
||||
@@ -5,8 +5,6 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
{
|
||||
ffStrbufSetStatic(&os->name, "Android");
|
||||
|
||||
ffStrbufSetStatic(&os->prettyName, "Android");
|
||||
|
||||
ffStrbufSetStatic(&os->id, "android");
|
||||
|
||||
ffSettingsGetAndroidProperty("ro.build.version.release", &os->version);
|
||||
|
||||
+11
-13
@@ -54,18 +54,18 @@ static bool detectOSCodeName(FFOSResult* os)
|
||||
case 14: ffStrbufSetStatic(&os->codename, "Mojave"); return true;
|
||||
case 13: ffStrbufSetStatic(&os->codename, "High Sierra"); return true;
|
||||
case 12: ffStrbufSetStatic(&os->codename, "Sierra"); return true;
|
||||
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 7: ffStrbufSetStatic(&os->codename, "Lion"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); return true;
|
||||
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); return true;
|
||||
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); return true;
|
||||
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); return true;
|
||||
case 7: ffStrbufSetStatic(&os->codename, "Lion"); return true;
|
||||
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
|
||||
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
|
||||
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
|
||||
case 3: ffStrbufSetStatic(&os->codename, "Panther"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 1: ffStrbufSetStatic(&os->codename, "Puma"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
|
||||
case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
|
||||
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,8 +106,6 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
if(os->buildID.length == 0)
|
||||
ffSysctlGetString("kern.osversion", &os->buildID);
|
||||
|
||||
if(os->prettyName.length == 0)
|
||||
ffStrbufSetStatic(&os->prettyName, "macOS");
|
||||
ffStrbufAppend(&os->versionID, &os->version);
|
||||
|
||||
if(!detectOSCodeName(os))
|
||||
|
||||
+49
-28
@@ -11,14 +11,6 @@
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
static inline bool allRelevantValuesSet(const FFOSResult* result)
|
||||
{
|
||||
return result->id.length > 0
|
||||
&& result->name.length > 0
|
||||
&& result->prettyName.length > 0
|
||||
;
|
||||
}
|
||||
|
||||
static bool parseLsbRelease(const char* fileName, FFOSResult* result)
|
||||
{
|
||||
return ffParsePropFileValues(fileName, 4, (FFpropquery[]) {
|
||||
@@ -46,12 +38,49 @@ static bool parseOsRelease(const char* fileName, FFOSResult* result)
|
||||
});
|
||||
}
|
||||
|
||||
// Common logic for detecting Armbian image version
|
||||
FF_MAYBE_UNUSED static bool detectArmbianVersion(FFOSResult* result)
|
||||
{
|
||||
if (ffStrbufStartsWithS(&result->prettyName, "Armbian ")) // Official Armbian release images
|
||||
ffStrbufSetS(&result->name, "Armbian");
|
||||
else if (ffStrbufStartsWithS(&result->prettyName, "Armbian-unofficial ")) // Unofficial Armbian image built from source
|
||||
ffStrbufSetS(&result->name, "Armbian (custom build)");
|
||||
else
|
||||
return false;
|
||||
ffStrbufSet(&result->idLike, &result->id);
|
||||
ffStrbufSetS(&result->id, "armbian");
|
||||
ffStrbufClear(&result->versionID);
|
||||
uint32_t versionStart = ffStrbufFirstIndexC(&result->prettyName, ' ') + 1;
|
||||
uint32_t versionEnd = ffStrbufNextIndexC(&result->prettyName, versionStart, ' ');
|
||||
ffStrbufSetNS(&result->versionID, versionEnd - versionStart, result->prettyName.chars + versionStart);
|
||||
return true;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static void getUbuntuFlavour(FFOSResult* result)
|
||||
{
|
||||
const char* xdgConfigDirs = getenv("XDG_CONFIG_DIRS");
|
||||
if(!ffStrSet(xdgConfigDirs))
|
||||
return;
|
||||
|
||||
if (detectArmbianVersion(result))
|
||||
return;
|
||||
else if(ffStrbufStartsWithS(&result->prettyName, "Linux Lite "))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Linux Lite");
|
||||
ffStrbufSetS(&result->id, "linuxlite");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Linux Lite "));
|
||||
return;
|
||||
}
|
||||
else if(ffStrbufStartsWithS(&result->prettyName, "Rhino Linux "))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Rhino Linux");
|
||||
ffStrbufSetS(&result->id, "rhinolinux");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Rhino Linux "));
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "kde") || ffStrContains(xdgConfigDirs, "plasma") || ffStrContains(xdgConfigDirs, "kubuntu"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Kubuntu");
|
||||
@@ -70,7 +99,7 @@ FF_MAYBE_UNUSED static void getUbuntuFlavour(FFOSResult* result)
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "lxde") || ffStrContains(xdgConfigDirs, "lubuntu"))
|
||||
if(ffStrContains(xdgConfigDirs, "lxqt") || ffStrContains(xdgConfigDirs, "lubuntu"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Lubuntu");
|
||||
ffStrbufSetS(&result->prettyName, "Lubuntu");
|
||||
@@ -155,17 +184,8 @@ FF_MAYBE_UNUSED static void getDebianVersion(FFOSResult* result)
|
||||
|
||||
FF_MAYBE_UNUSED static bool detectDebianDerived(FFOSResult* result)
|
||||
{
|
||||
if (ffStrbufStartsWithS(&result->prettyName, "Armbian ")) // Armbian 24.2.1 bookworm
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Armbian");
|
||||
ffStrbufSetS(&result->id, "armbian");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufClear(&result->versionID);
|
||||
uint32_t versionStart = ffStrbufFirstIndexC(&result->prettyName, ' ') + 1;
|
||||
uint32_t versionEnd = ffStrbufNextIndexC(&result->prettyName, versionStart, ' ');
|
||||
ffStrbufSetNS(&result->versionID, versionEnd - versionStart, result->prettyName.chars + versionStart);
|
||||
if (detectArmbianVersion(result))
|
||||
return true;
|
||||
}
|
||||
else if (ffStrbufStartsWithS(&result->name, "Loc-OS"))
|
||||
{
|
||||
ffStrbufSetS(&result->id, "locos");
|
||||
@@ -232,7 +252,9 @@ static void detectOS(FFOSResult* os)
|
||||
{
|
||||
#ifdef FF_CUSTOM_OS_RELEASE_PATH
|
||||
parseOsRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os);
|
||||
parseLsbRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os);
|
||||
#ifdef FF_CUSTOM_LSB_RELEASE_PATH
|
||||
parseLsbRelease(FF_STR(FF_CUSTOM_LSB_RELEASE_PATH), os);
|
||||
#endif
|
||||
return;
|
||||
#endif
|
||||
|
||||
@@ -247,18 +269,17 @@ static void detectOS(FFOSResult* os)
|
||||
if(os->prettyName.length == 0)
|
||||
ffStrbufAppendS(&os->prettyName, "Bedrock Linux");
|
||||
|
||||
if(parseOsRelease("/bedrock" FASTFETCH_TARGET_DIR_ETC "/os-release", os) && allRelevantValuesSet(os))
|
||||
return;
|
||||
parseOsRelease("/bedrock" FASTFETCH_TARGET_DIR_ETC "/os-release", os);
|
||||
return;
|
||||
}
|
||||
|
||||
// Refer: https://gist.github.com/natefoo/814c5bf936922dad97ff
|
||||
|
||||
if((parseOsRelease(FASTFETCH_TARGET_DIR_ETC "/os-release", os) ||
|
||||
parseLsbRelease(FASTFETCH_TARGET_DIR_ETC "/lsb-release", os)) &&
|
||||
allRelevantValuesSet(os))
|
||||
return;
|
||||
|
||||
parseOsRelease(FASTFETCH_TARGET_DIR_USR "/lib/os-release", os);
|
||||
parseOsRelease(FASTFETCH_TARGET_DIR_ETC "/os-release", os);
|
||||
if (os->id.length == 0 || os->version.length == 0 || os->prettyName.length == 0 || os->codename.length == 0)
|
||||
parseLsbRelease(FASTFETCH_TARGET_DIR_ETC "/lsb-release", os);
|
||||
if (os->id.length == 0 || os->name.length > 0 || os->prettyName.length > 0)
|
||||
parseOsRelease(FASTFETCH_TARGET_DIR_USR "/lib/os-release", os);
|
||||
}
|
||||
|
||||
void ffDetectOSImpl(FFOSResult* os)
|
||||
|
||||
@@ -13,6 +13,7 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
const wchar_t* rawName = BrandingFormatString(L"%WINDOWS_LONG%");
|
||||
ffStrbufSetWS(&os->variant, rawName);
|
||||
GlobalFree((HGLOBAL)rawName);
|
||||
ffStrbufSet(&os->prettyName, &os->variant);
|
||||
ffStrbufTrimRight(&os->variant, ' ');
|
||||
|
||||
//WMI returns the "Microsoft" prefix while BrandingFormatString doesn't. Make them consistent.
|
||||
@@ -22,14 +23,12 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
if(ffStrbufStartsWithS(&os->variant, "Windows "))
|
||||
{
|
||||
ffStrbufAppendS(&os->name, "Windows");
|
||||
ffStrbufAppendS(&os->prettyName, "Windows");
|
||||
|
||||
ffStrbufSubstrAfter(&os->variant, strlen("Windows ") - 1);
|
||||
|
||||
if(ffStrbufStartsWithS(&os->variant, "Server "))
|
||||
{
|
||||
ffStrbufAppendS(&os->name, " Server");
|
||||
ffStrbufAppendS(&os->prettyName, " Server");
|
||||
ffStrbufSubstrAfter(&os->variant, strlen(" Server") - 1);
|
||||
}
|
||||
|
||||
@@ -38,7 +37,7 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
ffStrbufSubstrAfter(&os->variant, index);
|
||||
|
||||
// Windows Server 20xx Rx
|
||||
if(ffStrbufEndsWithC(&os->prettyName, 'r'))
|
||||
if(ffStrbufEndsWithC(&os->name, 'r'))
|
||||
{
|
||||
if(os->variant.chars[0] == 'R' &&
|
||||
ffCharIsDigit(os->variant.chars[1]) &&
|
||||
@@ -56,6 +55,6 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
ffStrbufClear(&os->variant);
|
||||
}
|
||||
|
||||
ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars);
|
||||
ffStrbufAppendF(&os->id, "%s %s", os->name.chars, os->version.chars);
|
||||
ffStrbufSetStatic(&os->idLike, "Windows");
|
||||
}
|
||||
|
||||
@@ -85,3 +85,38 @@ bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t n
|
||||
ffStrbufAppendF(cacheContent, "%" PRIu32, num_elements);
|
||||
return ffWriteFileBuffer(cacheDir->chars, cacheContent);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
uint32_t ffPackagesGetNumElements(const char* dirname, bool isdir)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
|
||||
if(dirp == NULL)
|
||||
return 0;
|
||||
|
||||
uint32_t num_elements = 0;
|
||||
|
||||
struct dirent *entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
#ifndef __sun
|
||||
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
|
||||
ok = entry->d_type == (isdir ? DT_DIR : DT_REG);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (fstatat(dirfd(dirp), entry->d_name, &stbuf, 0) == 0)
|
||||
ok = isdir ? S_ISDIR(stbuf.st_mode) : S_ISREG(stbuf.st_mode);
|
||||
}
|
||||
|
||||
if(ok) ++num_elements;
|
||||
}
|
||||
|
||||
if(isdir && num_elements >= 2)
|
||||
num_elements -= 2; // accounting for . and ..
|
||||
|
||||
return num_elements;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
typedef struct FFPackagesResult
|
||||
{
|
||||
uint32_t am;
|
||||
uint32_t amSystem;
|
||||
uint32_t amUser;
|
||||
uint32_t apk;
|
||||
uint32_t brew;
|
||||
uint32_t brewCask;
|
||||
@@ -30,6 +31,7 @@ typedef struct FFPackagesResult
|
||||
uint32_t pacstall;
|
||||
uint32_t paludis;
|
||||
uint32_t pkg;
|
||||
uint32_t pkgsrc;
|
||||
uint32_t pkgtool;
|
||||
uint32_t qi;
|
||||
uint32_t rpm;
|
||||
@@ -47,3 +49,7 @@ typedef struct FFPackagesResult
|
||||
const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options);
|
||||
bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result);
|
||||
bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements);
|
||||
|
||||
#ifndef _WIN32
|
||||
uint32_t ffPackagesGetNumElements(const char* dirname, bool isdir);
|
||||
#endif
|
||||
|
||||
@@ -4,26 +4,6 @@
|
||||
#include "common/processing.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
static uint32_t getNumElements(const char* dirname, unsigned char type)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
|
||||
if(dirp == NULL)
|
||||
return 0;
|
||||
|
||||
uint32_t num_elements = 0;
|
||||
|
||||
struct dirent *entry;
|
||||
while((entry = readdir(dirp)) != NULL) {
|
||||
if(entry->d_type == type)
|
||||
++num_elements;
|
||||
}
|
||||
|
||||
if(type == DT_DIR)
|
||||
num_elements -= 2; // accounting for . and ..
|
||||
|
||||
return num_elements;
|
||||
}
|
||||
|
||||
static void countBrewPackages(const char* dirname, FFPackagesResult* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS(dirname);
|
||||
@@ -31,11 +11,11 @@ static void countBrewPackages(const char* dirname, FFPackagesResult* result)
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
|
||||
ffStrbufAppendS(&baseDir, "/Caskroom");
|
||||
result->brewCask += getNumElements(baseDir.chars, DT_DIR);
|
||||
result->brewCask += ffPackagesGetNumElements(baseDir.chars, true);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
|
||||
ffStrbufAppendS(&baseDir, "/Cellar");
|
||||
result->brew += getNumElements(baseDir.chars, DT_DIR);
|
||||
result->brew += ffPackagesGetNumElements(baseDir.chars, true);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
@@ -52,9 +32,9 @@ static void getBrewPackages(FFPackagesResult* result)
|
||||
static uint32_t countMacPortsPackages(const char* dirname)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS(dirname);
|
||||
ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT "/var/macports/software");
|
||||
ffStrbufAppendS(&baseDir, "/var/macports/software");
|
||||
|
||||
return getNumElements(baseDir.chars, DT_DIR);
|
||||
return ffPackagesGetNumElements(baseDir.chars, true);
|
||||
}
|
||||
|
||||
static uint32_t getMacPortsPackages()
|
||||
|
||||
@@ -7,33 +7,11 @@
|
||||
#include "detection/os/os.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
|
||||
if(dirp == NULL)
|
||||
return 0;
|
||||
|
||||
uint32_t num_elements = 0;
|
||||
|
||||
struct dirent *entry;
|
||||
while((entry = readdir(dirp)) != NULL) {
|
||||
if(entry->d_type == type)
|
||||
++num_elements;
|
||||
}
|
||||
|
||||
if(type == DT_DIR && num_elements >= 2)
|
||||
num_elements -= 2; // accounting for . and ..
|
||||
|
||||
return num_elements;
|
||||
}
|
||||
|
||||
static uint32_t getNumElements(FFstrbuf* baseDir, const char* dirname, unsigned char type)
|
||||
static uint32_t getNumElements(FFstrbuf* baseDir, const char* dirname, bool isdir)
|
||||
{
|
||||
uint32_t baseDirLength = baseDir->length;
|
||||
ffStrbufAppendS(baseDir, dirname);
|
||||
uint32_t num_elements = getNumElementsImpl(baseDir->chars, type);
|
||||
uint32_t num_elements = ffPackagesGetNumElements(baseDir->chars, isdir);
|
||||
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
||||
return num_elements;
|
||||
}
|
||||
@@ -332,10 +310,10 @@ static uint32_t getXBPS(FFstrbuf* baseDir, const char* dirname)
|
||||
|
||||
static uint32_t getSnap(FFstrbuf* baseDir)
|
||||
{
|
||||
uint32_t result = getNumElements(baseDir, "/snap", DT_DIR);
|
||||
uint32_t result = getNumElements(baseDir, "/snap", true);
|
||||
|
||||
if (result == 0)
|
||||
result = getNumElements(baseDir, "/var/lib/snapd/snap", DT_DIR);
|
||||
result = getNumElements(baseDir, "/var/lib/snapd/snap", true);
|
||||
|
||||
//Accounting for the /snap/bin folder
|
||||
return result > 0 ? result - 1 : 0;
|
||||
@@ -386,7 +364,29 @@ static uint32_t getRpmFromLibrpm(void)
|
||||
|
||||
#endif //FF_HAVE_RPM
|
||||
|
||||
static uint32_t getAM(FFstrbuf* baseDir)
|
||||
static uint32_t getAMPackages(FFstrbuf* baseDir)
|
||||
{
|
||||
uint32_t baseLength = baseDir->length;
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
|
||||
if (!dirp) return 0;
|
||||
|
||||
uint32_t result = 0;
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.') continue;
|
||||
if (entry->d_type == DT_DIR)
|
||||
{
|
||||
ffStrbufAppendF(baseDir, "/%s/remove", entry->d_name);
|
||||
if (ffPathExists(baseDir->chars, FF_PATHTYPE_FILE))
|
||||
++result;
|
||||
ffStrbufSubstrBefore(baseDir, baseLength);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t getAMSystem(FFstrbuf* baseDir)
|
||||
{
|
||||
// #771
|
||||
uint32_t baseDirLength = baseDir->length;
|
||||
@@ -401,28 +401,27 @@ static uint32_t getAM(FFstrbuf* baseDir)
|
||||
{
|
||||
++result; // `am` itself is counted as a package too
|
||||
ffStrbufSubstrBefore(baseDir, optDirLength);
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
|
||||
if(dirp)
|
||||
{
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.') continue;
|
||||
if (entry->d_type == DT_DIR)
|
||||
{
|
||||
ffStrbufAppendF(baseDir, "/%s/AM-updater", entry->d_name);
|
||||
if (ffPathExists(baseDir->chars, FF_PATHTYPE_FILE))
|
||||
++result;
|
||||
ffStrbufSubstrBefore(baseDir, optDirLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = getAMPackages(baseDir);
|
||||
}
|
||||
|
||||
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t getAMUser(void)
|
||||
{
|
||||
// check if $XDG_CONFIG_HOME/appman/appman-config exists
|
||||
FFstrbuf* baseDir = FF_LIST_GET(FFstrbuf, instance.state.platform.configDirs, 0);
|
||||
uint32_t baseLen = baseDir->length;
|
||||
ffStrbufAppendS(baseDir, "appman/appman-config");
|
||||
FF_STRBUF_AUTO_DESTROY packagesPath = ffStrbufCreate();
|
||||
if (ffReadFileBuffer(baseDir->chars, &packagesPath))
|
||||
ffStrbufTrimRightSpace(&packagesPath);
|
||||
ffStrbufSubstrBefore(baseDir, baseLen);
|
||||
|
||||
return packagesPath.length > 0 ? getAMPackages(&packagesPath) : 0;
|
||||
}
|
||||
|
||||
static int compareHash(const void* a, const void* b)
|
||||
{
|
||||
return memcmp(a, b, 32);
|
||||
@@ -480,7 +479,7 @@ static inline uint32_t getFlatpakRuntimePackagesArch(FFstrbuf* baseDir)
|
||||
{
|
||||
if(entry->d_type == DT_DIR && entry->d_name[0] != '.')
|
||||
{
|
||||
num_elements += getNumElements(baseDir, entry->d_name, DT_DIR);
|
||||
num_elements += getNumElements(baseDir, entry->d_name, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,7 +528,7 @@ static uint32_t getFlatpakPackages(FFstrbuf* baseDir, const char* dirname)
|
||||
uint32_t flatpakDirLength = baseDir->length;
|
||||
|
||||
ffStrbufAppendS(baseDir, "app");
|
||||
num_elements += getNumElementsImpl(baseDir->chars, DT_DIR);
|
||||
num_elements += ffPackagesGetNumElements(baseDir->chars, true);
|
||||
ffStrbufSubstrBefore(baseDir, flatpakDirLength);
|
||||
|
||||
num_elements += getFlatpakRuntimePackages(baseDir);
|
||||
@@ -545,34 +544,34 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_DPKG_BIT)) packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: install ok installed", "dpkg");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n", "lpkg");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_EMERGE_BIT)) packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", true);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getFlatpakPackages(baseDir, "/var/lib");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_NIX_BIT))
|
||||
{
|
||||
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
|
||||
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
|
||||
}
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PACMAN_BIT)) packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LPKGBUILD_BIT)) packageCounts->lpkgbuild += getNumElements(baseDir, "/opt/Loc-OS-LPKG/lpkgbuild/remove", DT_REG);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PKGTOOL_BIT)) packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PACMAN_BIT)) packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", true);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LPKGBUILD_BIT)) packageCounts->lpkgbuild += getNumElements(baseDir, "/opt/Loc-OS-LPKG/lpkgbuild/remove", false);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PKGTOOL_BIT)) packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", false);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages", "rpm");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_SNAP_BIT)) packageCounts->snap += getSnap(baseDir);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_XBPS_BIT)) packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_BREW_BIT))
|
||||
{
|
||||
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
|
||||
packageCounts->brew += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Cellar", DT_DIR);
|
||||
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", true);
|
||||
packageCounts->brew += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Cellar", true);
|
||||
}
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PALUDIS_BIT)) packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:", "opkg"); // openwrt
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->am = getAM(baseDir);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->amSystem = getAMSystem(baseDir);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:", "sorcery");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_GUIX_BIT))
|
||||
{
|
||||
packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile");
|
||||
}
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PACSTALL_BIT)) packageCounts->pacstall += getNumElements(baseDir, "/var/lib/pacstall/metadata", DT_REG);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", true);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PACSTALL_BIT)) packageCounts->pacstall += getNumElements(baseDir, "/var/lib/pacstall/metadata", false);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_QI_BIT)) packageCounts->qi += getNumStrings(baseDir, "/var/qi/installed_packages.list", "\n", "qi");
|
||||
}
|
||||
|
||||
@@ -678,4 +677,7 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT))
|
||||
result->flatpakUser = getFlatpakPackages(&baseDir, "/.local/share");
|
||||
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT))
|
||||
result->amUser = getAMUser();
|
||||
}
|
||||
|
||||
@@ -2,36 +2,13 @@
|
||||
|
||||
#include "common/io/io.h"
|
||||
|
||||
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
|
||||
if(dirp == NULL)
|
||||
return 0;
|
||||
|
||||
uint32_t num_elements = 0;
|
||||
|
||||
struct dirent *entry;
|
||||
while((entry = readdir(dirp)) != NULL) {
|
||||
if(entry->d_type == type)
|
||||
++num_elements;
|
||||
}
|
||||
|
||||
if(type == DT_DIR && num_elements >= 2)
|
||||
num_elements -= 2; // accounting for . and ..
|
||||
|
||||
return num_elements;
|
||||
}
|
||||
|
||||
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||
{
|
||||
#if __OpenBSD__
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT))
|
||||
{
|
||||
result->pkg = getNumElementsImpl(FASTFETCH_TARGET_DIR_ROOT
|
||||
#if __OpenBSD
|
||||
"/var/db/pkg"
|
||||
#else
|
||||
"/usr/pkg/pkgdb"
|
||||
#endif
|
||||
, DT_DIR);
|
||||
}
|
||||
result->pkg = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg", true);
|
||||
#elif __NetBSD__
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PKGSRC_BIT))
|
||||
result->pkgsrc = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/usr/pkg/pkgdb", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "packages.h"
|
||||
#include <dirent.h>
|
||||
|
||||
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||
{
|
||||
@@ -12,4 +13,6 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||
result->pkg = (uint32_t) yyjson_get_uint(packageCount);
|
||||
}
|
||||
}
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_PKGSRC_BIT))
|
||||
result->pkgsrc = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/usr/pkg/pkgdb", true);
|
||||
}
|
||||
|
||||
@@ -80,24 +80,28 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption
|
||||
|
||||
{
|
||||
ffStrbufInit(&device->interconnect);
|
||||
char pathSysDeviceReal[PATH_MAX];
|
||||
ssize_t pathLength = readlinkat(dfd, "device", pathSysDeviceReal, ARRAY_SIZE(pathSysDeviceReal) - 1);
|
||||
if (pathLength > 0)
|
||||
if (ffStrStartsWith(devName, "nvme"))
|
||||
ffStrbufSetStatic(&device->interconnect, "NVMe");
|
||||
else
|
||||
{
|
||||
pathSysDeviceReal[pathLength] = '\0';
|
||||
|
||||
if (strstr(pathSysDeviceReal, "/usb") != NULL)
|
||||
ffStrbufSetS(&device->interconnect, "USB");
|
||||
else if (strstr(pathSysDeviceReal, "/nvme") != NULL)
|
||||
ffStrbufSetS(&device->interconnect, "NVMe");
|
||||
else if (strstr(pathSysDeviceReal, "/ata") != NULL)
|
||||
ffStrbufSetS(&device->interconnect, "ATA");
|
||||
else if (strstr(pathSysDeviceReal, "/scsi") != NULL)
|
||||
ffStrbufSetS(&device->interconnect, "SCSI");
|
||||
else
|
||||
char pathSysDeviceLink[64];
|
||||
snprintf(pathSysDeviceLink, ARRAY_SIZE(pathSysDeviceLink), "/sys/block/%s/device", devName);
|
||||
char pathSysDeviceReal[PATH_MAX];
|
||||
if (realpath(pathSysDeviceLink, pathSysDeviceReal))
|
||||
{
|
||||
if (ffAppendFileBufferRelative(devfd, "transport", &device->interconnect))
|
||||
ffStrbufTrimRightSpace(&device->interconnect);
|
||||
if (strstr(pathSysDeviceReal, "/usb") != NULL)
|
||||
ffStrbufSetStatic(&device->interconnect, "USB");
|
||||
else if (strstr(pathSysDeviceReal, "/ata") != NULL)
|
||||
ffStrbufSetStatic(&device->interconnect, "ATA");
|
||||
else if (strstr(pathSysDeviceReal, "/scsi") != NULL)
|
||||
ffStrbufSetStatic(&device->interconnect, "SCSI");
|
||||
else if (strstr(pathSysDeviceReal, "/nvme") != NULL)
|
||||
ffStrbufSetStatic(&device->interconnect, "NVMe");
|
||||
else
|
||||
{
|
||||
if (ffAppendFileBufferRelative(devfd, "transport", &device->interconnect))
|
||||
ffStrbufTrimRightSpace(&device->interconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,7 +173,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
if (devName[0] == '.')
|
||||
continue;
|
||||
|
||||
char pathSysBlock[ARRAY_SIZE("/sys/block/") + ARRAY_SIZE(sysBlockEntry->d_name)];
|
||||
char pathSysBlock[sizeof("/sys/block/") + sizeof(sysBlockEntry->d_name)];
|
||||
snprintf(pathSysBlock, ARRAY_SIZE(pathSysBlock), "/sys/block/%s", devName);
|
||||
|
||||
int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
||||
|
||||
@@ -23,6 +23,7 @@ static inline const char* getVendorString(unsigned vendorId)
|
||||
|
||||
void FFPhysicalMemoryUpdateVendorString(FFPhysicalMemoryResult* device)
|
||||
{
|
||||
if (device->vendor.length == 0) return;
|
||||
if (ffStrbufEqualS(&device->vendor, "Unknown"))
|
||||
{
|
||||
ffStrbufClear(&device->vendor);
|
||||
|
||||
@@ -191,6 +191,7 @@ const char* ffDetectPhysicalMemory(FFlist* result)
|
||||
device->maxSpeed = data->Speed == 0xFFFF ? data->ExtendedSpeed : data->Speed;
|
||||
|
||||
ffStrbufSetStatic(&device->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
|
||||
ffCleanUpSmbiosValue(&device->vendor);
|
||||
FFPhysicalMemoryUpdateVendorString(device);
|
||||
|
||||
ffStrbufSetStatic(&device->serial, ffSmbiosLocateString(strings, data->SerialNumber));
|
||||
|
||||
@@ -8,6 +8,7 @@ typedef struct FFSoundDevice
|
||||
{
|
||||
FFstrbuf identifier;
|
||||
FFstrbuf name;
|
||||
FFstrbuf platformApi;
|
||||
uint8_t volume; // 0-100%
|
||||
bool main;
|
||||
bool active;
|
||||
|
||||
@@ -73,6 +73,7 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
|
||||
device->volume = FF_SOUND_VOLUME_UNKNOWN;
|
||||
ffStrbufInitF(&device->identifier, "%u", (unsigned) deviceId);
|
||||
ffStrbufInit(&device->name);
|
||||
ffStrbufInitStatic(&device->platformApi, "Core Audio");
|
||||
ffCfStrGetString(name, &device->name);
|
||||
|
||||
uint32_t muted;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user