mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2025-02-20 11:43:27 +08:00
commit
7c15d0ce88
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
@ -146,7 +146,7 @@ jobs:
|
||||
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
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
@ -185,7 +185,7 @@ jobs:
|
||||
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
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
@ -220,7 +220,7 @@ jobs:
|
||||
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
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
@ -259,7 +259,7 @@ jobs:
|
||||
- name: run
|
||||
run: |
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
@ -300,7 +300,7 @@ jobs:
|
||||
- name: run
|
||||
run: |
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
@ -348,7 +348,7 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
@ -477,7 +477,7 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
@ -547,7 +547,7 @@ jobs:
|
||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x86.dll
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
run: time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
65
CHANGELOG.md
65
CHANGELOG.md
@ -1,3 +1,68 @@
|
||||
# 2.19.0
|
||||
|
||||
Changes:
|
||||
* JSON option `modules.cpu.freqNdigits` has been renamed and moved to `display.freq.ndigits`
|
||||
* Previously: `{ "modules": { "type": "cpu", "freqNdigits": 2 } }`
|
||||
* Now: `{ "display": { "freq": { "ndigits": 2 } } }`
|
||||
* This option now affects GPU frequency too
|
||||
* By default, frequencies are displayed in *GHz*. Set `display.freq.ndigits` to `-1` to display them in *MHz*
|
||||
* JSON option `display.binaryPrefix` has been moved to `display.size.binaryPrefix`
|
||||
* Previously: `{ "display": { "binaryPrefix": "IEC" } }`
|
||||
* Now: `{ "display": { "size": { "binaryPrefix": "IEC" } } }`
|
||||
|
||||
Features:
|
||||
* Print physical diagonal length if supported (Display)
|
||||
* Detect display type in X11 mode (Display)
|
||||
* Assume displays connected via DisplayPort are external monitors (Display, Linux)
|
||||
* Support GPU frequency detection for Intel XE driver (GPU, Linux)
|
||||
* Detect init system on Android (InitSystem, Android)
|
||||
* Use background to display color blocks (Colors)
|
||||
* To fix weird vertical black lines in some terminals and match the behavior of neofetch (#1094)
|
||||
* Can be reverted to old behavior with `--colors-symbol block`
|
||||
* Support Zed terminal version detection (Terminal)
|
||||
* Improve wezterm font detection (TerminalFont)
|
||||
* Add option `--separator-length`
|
||||
* Support GPU frequency detection for Apple Silicon (GPU, macOS)
|
||||
* Detect maximum refresh rate (#1101, Monitor)
|
||||
* Detect if HDR mode is supported and enabled (Windows, Display / Monitor)
|
||||
* Support physical monitor info detection for FreeBSD and SunOS (Monitor)
|
||||
* Support defining constant strings in JSON config file, which can be used to dedupe formattion strings
|
||||
```jsonc
|
||||
{
|
||||
"display": {
|
||||
"constants": [
|
||||
"Hello", // {$1}
|
||||
"world" // {$2}
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "{$1} {$2}!" // print "Hello world!"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "{$2} {$1}" // print "world Hello"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Bugfixes:
|
||||
* Fix some presets
|
||||
* Better detection for XTerm terminal fonts (#1095, TerminalFont, Linux)
|
||||
* Remove debug output (#1097, Windows)
|
||||
* Fix command line option `--gpu-hide-type` doesn't work (#1098, GPU)
|
||||
* Fix wrong date on Raspbian 10 (#1108, DateTime, Linux)
|
||||
* Use `brightness` instead of `actuall_brightness` when detecting current brightness level (Brightness, Linux)
|
||||
* Ref: https://bugzilla.kernel.org/show_bug.cgi?id=203905
|
||||
* Fix buffer overflow with long font family names when detecting kitty term font (TerminalFont)
|
||||
* Fix some typos
|
||||
|
||||
Logos:
|
||||
* Update void_small
|
||||
* Add ALT Linux
|
||||
|
||||
# 2.18.1
|
||||
|
||||
Fix a regression introduced in v2.18.0
|
||||
|
@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.18.1
|
||||
VERSION 2.19.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@ -591,7 +591,7 @@ elseif(BSD)
|
||||
src/detection/gamepad/gamepad_bsd.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_bsd.c
|
||||
src/detection/monitor/monitor_nosupport.c
|
||||
src/detection/monitor/monitor_linux.c
|
||||
src/detection/netio/netio_bsd.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_linux.c
|
||||
@ -796,7 +796,7 @@ elseif(SunOS)
|
||||
src/detection/gamepad/gamepad_nosupport.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_sunos.c
|
||||
src/detection/monitor/monitor_nosupport.c
|
||||
src/detection/monitor/monitor_linux.c
|
||||
src/detection/netio/netio_sunos.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_sunos.c
|
||||
|
@ -126,6 +126,10 @@ Fastfetch uses JSON (with comments) for configuration. I suggest you use an IDE
|
||||
|
||||
Alternatively, you can refer to the presets in [`presets` directory](https://github.com/fastfetch-cli/fastfetch/tree/dev/presets).
|
||||
|
||||
The **correct** way to edit the configuration:
|
||||
|
||||
[](https://asciinema.org/a/1uF6sTPGKrHKI1MVaFcikINSQ)
|
||||
|
||||
### Q: I WANT THE DOCUMENTATION!
|
||||
|
||||
[Here is the documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Json-Schema). It is generated from [JSON schema](https://github.com/fastfetch-cli/fastfetch/blob/dev/doc/json_schema.json) but you won't like it.
|
||||
@ -169,6 +173,10 @@ The p10k doc clearly states that you should NOT print anything to stdout after `
|
||||
|
||||
You can always use `fastfetch --pipe false` to force fastfetch running in colorful mode.
|
||||
|
||||
### Q: Why do fastfetch and neofetch show different memory usage result?
|
||||
|
||||
See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
|
||||
|
||||
### 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:
|
||||
|
@ -83,12 +83,12 @@ __fastfetch_complete_logo_type()
|
||||
|
||||
__fastfetch_complete_binary_prefix()
|
||||
{
|
||||
local __ff_binary_prefixes=(
|
||||
local __ff_size_binary_prefixes=(
|
||||
"iec"
|
||||
"si"
|
||||
"jedec"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_binary_prefixes[*]}" -- "$CURRENT_WORD"))
|
||||
COMPREPLY=($(compgen -W "${__ff_size_binary_prefixes[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_gl()
|
||||
|
12
debian/changelog
vendored
12
debian/changelog
vendored
@ -1,3 +1,15 @@
|
||||
fastfetch (2.18.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.18.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 11 Jul 2024 14:32:15 +0800
|
||||
|
||||
fastfetch (2.18.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.18.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 10 Jul 2024 16:46:32 +0800
|
||||
|
||||
fastfetch (2.17.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.17.2
|
||||
|
2
debian/files
vendored
2
debian/files
vendored
@ -1 +1 @@
|
||||
fastfetch_2.17.2_source.buildinfo universe/utils optional
|
||||
fastfetch_2.18.1_source.buildinfo universe/utils optional
|
||||
|
@ -98,7 +98,7 @@ config files, see the CONFIGURATION section
|
||||
|
||||
.B \-\-gen\-config \fI[file]
|
||||
Generate a config file with options specified on the command line.
|
||||
If \fIfile\fR is specified, the configuration will written to the
|
||||
If \fIfile\fR is specified, the configuration will be written to the
|
||||
file, otherwise it will be written to stdout.
|
||||
.TP
|
||||
|
||||
|
@ -424,29 +424,29 @@
|
||||
"minimum": 0,
|
||||
"default": 0
|
||||
},
|
||||
"binaryPrefix": {
|
||||
"type": "string",
|
||||
"description": "Set the binary prefix to used when printing bytes",
|
||||
"oneOf": [
|
||||
{
|
||||
"const": "iec",
|
||||
"description": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)"
|
||||
},
|
||||
{
|
||||
"const": "si",
|
||||
"description": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ..."
|
||||
},
|
||||
{
|
||||
"const": "jedec",
|
||||
"description": "1024 Bytes = 1 kB, 1024 K = 1 MB, ..."
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Set how a size value should be displayed",
|
||||
"properties": {
|
||||
"binaryPrefix": {
|
||||
"type": "string",
|
||||
"description": "Set the binary prefix to used when formatting sizes",
|
||||
"oneOf": [
|
||||
{
|
||||
"const": "iec",
|
||||
"description": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)"
|
||||
},
|
||||
{
|
||||
"const": "si",
|
||||
"description": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ..."
|
||||
},
|
||||
{
|
||||
"const": "jedec",
|
||||
"description": "1024 Bytes = 1 kB, 1024 K = 1 MB, ..."
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxPrefix": {
|
||||
"type": "string",
|
||||
"description": "Set the largest binary prefix to use when formatting sizes",
|
||||
@ -574,10 +574,31 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"freq": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Set how frequency values should be displayed",
|
||||
"properties": {
|
||||
"ndigits": {
|
||||
"type": "integer",
|
||||
"description": "Set the number of digits to keep after the decimal point when formatting frequency values\nA positive value will show the frequency in GHz of decimal\n-1 will show the frequency in MHz",
|
||||
"minimum": -1,
|
||||
"maximum": 9,
|
||||
"default": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"noBuffer": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to disable the stdout application buffer",
|
||||
"default": false
|
||||
},
|
||||
"constants": {
|
||||
"type": "array",
|
||||
"description": "List of strings to be used in custom format of modules",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1096,13 +1117,6 @@
|
||||
"temp": {
|
||||
"$ref": "#/$defs/temperature"
|
||||
},
|
||||
"freqNdigits": {
|
||||
"description": "Set the number of digits to keep after the decimal point when printing CPU frequency",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 9,
|
||||
"default": 2
|
||||
},
|
||||
"showPeCoreCount": {
|
||||
"description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
|
||||
"type": "boolean",
|
||||
@ -1173,13 +1187,14 @@
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"block",
|
||||
"background",
|
||||
"circle",
|
||||
"diamond",
|
||||
"triangle",
|
||||
"square",
|
||||
"star"
|
||||
],
|
||||
"default": "block"
|
||||
"default": "background"
|
||||
},
|
||||
"paddingLeft": {
|
||||
"description": "Set the number of white spaces to print before the symbol",
|
||||
@ -1940,12 +1955,19 @@
|
||||
"const": "separator"
|
||||
},
|
||||
"string": {
|
||||
"description": "Set the string to be printed",
|
||||
"description": "Set the string to be printed by the separator line",
|
||||
"type": "string",
|
||||
"default": "-"
|
||||
},
|
||||
"outputColor": {
|
||||
"description": "Set the color of the separator line",
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"length": {
|
||||
"description": "Set the length of the separator line, or 0 to auto-detect",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9,12 +9,15 @@
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": " -> "
|
||||
"separator": " -> ",
|
||||
"constants": [
|
||||
"──────────────────────────────"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "┌────────────────────────────────────────────────────────────┐",
|
||||
"format": "┌{$1}{$1}┐",
|
||||
"outputColor": "90"
|
||||
},
|
||||
{
|
||||
@ -23,7 +26,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "└────────────────────────────────────────────────────────────┘",
|
||||
"format": "└{$1}{$1}┘",
|
||||
"outputColor": "90"
|
||||
},
|
||||
{
|
||||
@ -32,7 +35,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "┌────────────────────────────────────────────────────────────┐",
|
||||
"format": "┌{$1}{$1}┐",
|
||||
"outputColor": "90"
|
||||
},
|
||||
{
|
||||
@ -142,7 +145,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "└────────────────────────────────────────────────────────────┘",
|
||||
"format": "└{$1}{$1}┘",
|
||||
"outputColor": "90"
|
||||
},
|
||||
"break",
|
||||
|
@ -7,7 +7,10 @@
|
||||
"separator": "-> ",
|
||||
"color": {
|
||||
"separator": "1"
|
||||
}
|
||||
},
|
||||
"constants": [
|
||||
"─────────────────────────────"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
@ -17,7 +20,7 @@
|
||||
"break",
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "┌───────────────────────────── {#1}System Information{#} ─────────────────────────────┐"
|
||||
"format": "┌{$1} {#1}System Information{#} {$1}┐"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
@ -95,7 +98,7 @@
|
||||
"break",
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "└──────────────────────────────────────────────────────────────────────────────┘"
|
||||
"format": "└{$1}────────────────────{$1}┘"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
|
@ -17,56 +17,55 @@
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
// draw borders first to make colors of left and right border consistant
|
||||
"key": "│ │\u001b[11D{#31} user",
|
||||
"key": "│ {#31} user {#keys}│",
|
||||
"type": "title",
|
||||
"format": "{1}"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#32} hname",
|
||||
"key": "│ {#32} hname {#keys}│",
|
||||
"type": "title",
|
||||
"format": "{2}"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#33} uptime",
|
||||
"key": "│ {#33} uptime {#keys}│",
|
||||
"type": "uptime"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#34} distro",
|
||||
"key": "│ {#34} distro {#keys}│",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#35} kernel",
|
||||
"key": "│ {#35} kernel {#keys}│",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#36} desktop",
|
||||
"key": "│ {#36} desktop {#keys}│",
|
||||
"type": "de"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#31} term",
|
||||
"key": "│ {#31} term {#keys}│",
|
||||
"type": "terminal"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#32} shell",
|
||||
"key": "│ {#32} shell {#keys}│",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#33} cpu",
|
||||
"key": "│ {#33} cpu {#keys}│",
|
||||
"type": "cpu",
|
||||
"showPeCoreCount": true
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#34} disk",
|
||||
"key": "│ {#34} disk {#keys}│",
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#35} memory",
|
||||
"key": "│ {#35} memory {#keys}│",
|
||||
"type": "memory"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#36} network",
|
||||
"key": "│ {#36} network {#keys}│",
|
||||
"type": "localip",
|
||||
"format": "{1} ({4})"
|
||||
},
|
||||
@ -75,7 +74,7 @@
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"key": "│ │\u001b[11D{#39} colors",
|
||||
"key": "│ {#39} colors {#keys}│",
|
||||
"type": "colors",
|
||||
"symbol": "circle"
|
||||
},
|
||||
|
@ -17,56 +17,55 @@
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
// draw borders first to make colors of left and right border consistant
|
||||
"key": "• •\u001b[11D{#31} user",
|
||||
"key": "• {#31} user {#keys}•",
|
||||
"type": "title",
|
||||
"format": "{1}"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#32} hname",
|
||||
"key": "• {#32} hname {#keys}•",
|
||||
"type": "title",
|
||||
"format": "{2}"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#33} uptime",
|
||||
"key": "• {#33} uptime {#keys}•",
|
||||
"type": "uptime"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#34} distro",
|
||||
"key": "• {#34} distro {#keys}•",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#35} kernel",
|
||||
"key": "• {#35} kernel {#keys}•",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#36} desktop",
|
||||
"key": "• {#36} desktop {#keys}•",
|
||||
"type": "de"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#31} term",
|
||||
"key": "• {#31} term {#keys}•",
|
||||
"type": "terminal"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#32} shell",
|
||||
"key": "• {#32} shell {#keys}•",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#33} cpu",
|
||||
"key": "• {#33} cpu {#keys}•",
|
||||
"type": "cpu",
|
||||
"showPeCoreCount": true
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#34} disk",
|
||||
"key": "• {#34} disk {#keys}•",
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#35} memory",
|
||||
"key": "• {#35} memory {#keys}•",
|
||||
"type": "memory"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#36} network",
|
||||
"key": "• {#36} network {#keys}•",
|
||||
"type": "localip",
|
||||
"format": "{1} ({4})"
|
||||
},
|
||||
@ -75,7 +74,7 @@
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"key": "• •\u001b[11D{#39} colors",
|
||||
"key": "• {#39} colors {#keys}•",
|
||||
"type": "colors",
|
||||
"symbol": "circle"
|
||||
},
|
||||
|
@ -11,72 +11,76 @@
|
||||
"separator": "> ",
|
||||
"color": {
|
||||
"separator": "red"
|
||||
}
|
||||
},
|
||||
"constants": [
|
||||
"───────────────────────────────────────────────────────────────────────────",
|
||||
"│\u001b[75C│\u001b[75D"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"format": "{#1}{#keys}╭───────────────────────────────────────────────────────────────────────────╮\u001b[76D {6}{7}{8} 🖥 ",
|
||||
"format": "{#1}{#keys}╭{$1}╮\u001b[76D {6}{7}{8} 🖥 ",
|
||||
"type": "title"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#31} kernel ",
|
||||
"key": "{$2}{#31} kernel ",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#32} uptime ",
|
||||
"key": "{$2}{#32} uptime ",
|
||||
"type": "uptime"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#33} distro ",
|
||||
"key": "{$2}{#33} distro ",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#34} desktop ",
|
||||
"key": "{$2}{#34} desktop ",
|
||||
"type": "de"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#35} term ",
|
||||
"key": "{$2}{#35} term ",
|
||||
"type": "terminal"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#36} shell ",
|
||||
"key": "{$2}{#36} shell ",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#35} cpu ",
|
||||
"key": "{$2}{#35} cpu ",
|
||||
"type": "cpu",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#34} gpu ",
|
||||
"key": "{$2}{#34} gpu ",
|
||||
"type": "gpu"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#33} disk ",
|
||||
"key": "{$2}{#33} disk ",
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#32} memory ",
|
||||
"key": "{$2}{#32} memory ",
|
||||
"type": "memory"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#31} network ",
|
||||
"key": "{$2}{#31} network ",
|
||||
"type": "localip",
|
||||
"format": "{1} ({4})"
|
||||
},
|
||||
{
|
||||
"format": "{#1}{#keys}├───────────────────────────────────────────────────────────────────────────┤",
|
||||
"format": "{#1}{#keys}├{$1}┤",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"key": "│\u001b[75C│\u001b[75D{#39} colors ",
|
||||
"key": "{$2}{#39} colors ",
|
||||
"type": "colors",
|
||||
"symbol": "circle"
|
||||
},
|
||||
{
|
||||
"format": "{#1}{#keys}╰───────────────────────────────────────────────────────────────────────────╯",
|
||||
"format": "{#1}{#keys}╰{$1}╯",
|
||||
"type": "custom"
|
||||
}
|
||||
]
|
||||
|
@ -11,72 +11,76 @@
|
||||
"separator": "> ",
|
||||
"color": {
|
||||
"separator": "red"
|
||||
}
|
||||
},
|
||||
"constants": [
|
||||
"═══════════════════════════════════════════════════════════════════════════",
|
||||
"║\u001b[75C║\u001b[75D"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"format": "{#1}{#keys}╔═══════════════════════════════════════════════════════════════════════════╗\u001b[76D {6}{7}{8} 💻 ",
|
||||
"format": "{#1}{#keys}╔{$1}╗\u001b[76D {6}{7}{8} 💻 ",
|
||||
"type": "title"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#31} kernel ",
|
||||
"key": "{$2}{#31} kernel ",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#32} uptime ",
|
||||
"key": "{$2}{#32} uptime ",
|
||||
"type": "uptime"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#33} distro ",
|
||||
"key": "{$2}{#33} distro ",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#34} desktop ",
|
||||
"key": "{$2}{#34} desktop ",
|
||||
"type": "de"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#35} term ",
|
||||
"key": "{$2}{#35} term ",
|
||||
"type": "terminal"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#36} shell ",
|
||||
"key": "{$2}{#36} shell ",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#35} cpu ",
|
||||
"key": "{$2}{#35} cpu ",
|
||||
"type": "cpu",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#34} gpu ",
|
||||
"key": "{$2}{#34} gpu ",
|
||||
"type": "gpu"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#33} disk ",
|
||||
"key": "{$2}{#33} disk ",
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#32} memory ",
|
||||
"key": "{$2}{#32} memory ",
|
||||
"type": "memory"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#31} network ",
|
||||
"key": "{$2}{#31} network ",
|
||||
"type": "localip",
|
||||
"format": "{1} ({4})"
|
||||
},
|
||||
{
|
||||
"format": "{#1}{#keys}╠═══════════════════════════════════════════════════════════════════════════╣",
|
||||
"format": "{#1}{#keys}╠{$1}╣",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"key": "║\u001b[75C║\u001b[75D{#39} colors ",
|
||||
"key": "{$2}{#39} colors ",
|
||||
"type": "colors",
|
||||
"symbol": "circle"
|
||||
},
|
||||
{
|
||||
"format": "{#1}{#keys}╚═══════════════════════════════════════════════════════════════════════════╝",
|
||||
"format": "{#1}{#keys}╚{$1}╝",
|
||||
"type": "custom"
|
||||
}
|
||||
]
|
||||
|
@ -12,7 +12,7 @@
|
||||
"logo": {
|
||||
"source": " _____ _____ _____ _____ _____ _____ _____ _____ _____\n| __| _ | __|_ _| __| __|_ _| | | |\n| __| |__ | | | | __| __| | | | --| |\n|__| |__|__|_____| |_| |__| |_____| |_| |_____|__|__|",
|
||||
"type": "data",
|
||||
"separate": true,
|
||||
"position": "top",
|
||||
"padding": {
|
||||
"right": 2
|
||||
}
|
||||
|
@ -10,13 +10,16 @@
|
||||
// "height": 12
|
||||
// },
|
||||
"display": {
|
||||
"separator": " "
|
||||
"separator": " ",
|
||||
"constants": [
|
||||
"───────────────"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom", // HardwareStart
|
||||
// {#1} is equivalent to `\u001b[1m`. {#} is equivalent to `\u001b[m`
|
||||
"format": "┌─────────── {#1}Hardware Information{#} ───────────┐"
|
||||
"format": "┌{$1} {#1}Hardware Information{#} {$1}┐"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
@ -72,12 +75,12 @@
|
||||
},
|
||||
{
|
||||
"type": "custom", // SoftwareStart
|
||||
"format": "├─────────── {#1}Software Information{#} ───────────┤"
|
||||
"format": "├{$1} {#1}Software Information{#} {$1}┤"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": " ",
|
||||
"format": "{1}@{2}"
|
||||
"format": "{1}${2}"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
@ -156,7 +159,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom", // InformationEnd
|
||||
"format": "└────────────────────────────────────────────┘"
|
||||
"format": "└{$1}──────────────────────{$1}┘"
|
||||
},
|
||||
{
|
||||
"type": "colors",
|
||||
|
@ -15,7 +15,10 @@
|
||||
"charElapsed": "█",
|
||||
"charTotal": "░",
|
||||
"width": 40
|
||||
}
|
||||
},
|
||||
"constants": [
|
||||
"\u001b[42C"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
@ -41,11 +44,11 @@
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "│ OS │\u001b[42C"
|
||||
"key": "│ OS │{$1}"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "│ KERNEL │\u001b[42C"
|
||||
"key": "│ KERNEL │{$1}"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
@ -53,34 +56,34 @@
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "│ HOSTNAME │\u001b[42C",
|
||||
"key": "│ HOSTNAME │{$1}",
|
||||
"format": "{host-name}"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": "│ CLIENT IP │\u001b[42C",
|
||||
"key": "│ CLIENT IP │{$1}",
|
||||
"format": "{ipv4}"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": "│ MAC ADDR │\u001b[42C",
|
||||
"key": "│ MAC ADDR │{$1}",
|
||||
"format": "{mac} ({ifname})",
|
||||
"showIPv4": false,
|
||||
"showMac": true
|
||||
},
|
||||
{
|
||||
"type": "dns",
|
||||
"key": "│ DNS │\u001b[42C",
|
||||
"key": "│ DNS │{$1}",
|
||||
"showType": "ipv4"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "│ USER │\u001b[42C",
|
||||
"key": "│ USER │{$1}",
|
||||
"format": "{user-name}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "│ MACHINE │\u001b[42C",
|
||||
"key": "│ MACHINE │{$1}",
|
||||
"format": "{name}"
|
||||
},
|
||||
{
|
||||
@ -89,25 +92,25 @@
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ PROCESSOR │\u001b[42C",
|
||||
"key": "│ PROCESSOR │{$1}",
|
||||
"format": "{name}"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ CORES │\u001b[42C",
|
||||
"key": "│ CORES │{$1}",
|
||||
"format": "{cores-physical} PHYSICAL CORES / {cores-logical} THREADS",
|
||||
"showPeCoreCount": false
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ CPU FREQ │\u001b[42C",
|
||||
"key": "│ CPU FREQ │{$1}",
|
||||
"format": "{freq-max}{/freq-max}{freq-base}{/} GHz"
|
||||
},
|
||||
{
|
||||
"type": "loadavg",
|
||||
"compact": false,
|
||||
// {duration} is not fixed length, hack it
|
||||
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│\u001b[42C"
|
||||
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
@ -115,12 +118,12 @@
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ MEMORY │\u001b[42C",
|
||||
"key": "│ MEMORY │{$1}",
|
||||
"format": "{used} / {total} [{percentage}]"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ USAGE │\u001b[42C",
|
||||
"key": "│ USAGE │{$1}",
|
||||
"format": ""
|
||||
},
|
||||
{
|
||||
@ -129,13 +132,13 @@
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "│ VOLUME │\u001b[42C",
|
||||
"key": "│ VOLUME │{$1}",
|
||||
"format": "{size-used} / {size-total} [{size-percentage}]",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "│ DISK USAGE │\u001b[42C",
|
||||
"key": "│ DISK USAGE │{$1}",
|
||||
"format": ""
|
||||
},
|
||||
{
|
||||
@ -144,13 +147,13 @@
|
||||
},
|
||||
{
|
||||
"type": "users",
|
||||
"key": "│ LAST LOGIN │\u001b[42C",
|
||||
"key": "│ LAST LOGIN │{$1}",
|
||||
"format": "{login-time}{?client-ip} ({client-ip})",
|
||||
"myselfOnly": true
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "│ UPTIME │\u001b[42C"
|
||||
"key": "│ UPTIME │{$1}"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
|
@ -3,39 +3,44 @@
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"constants": [
|
||||
"██ "
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"key": "██ Distro",
|
||||
"key": "{$1}Distro",
|
||||
"keyColor": "38;5;210",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "██ Kernel",
|
||||
"key": "{$1}Kernel",
|
||||
"keyColor": "38;5;84",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "██ Shell",
|
||||
"key": "{$1}Shell",
|
||||
"keyColor": "38;5;147",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "██ Packages",
|
||||
"key": "{$1}Packages",
|
||||
"keyColor": "38;5;200",
|
||||
"type": "packages"
|
||||
},
|
||||
{
|
||||
"key": "██ WM",
|
||||
"key": "{$1}WM",
|
||||
"keyColor": "38;5;44",
|
||||
"type": "wm"
|
||||
},
|
||||
{
|
||||
"key": "██ CPU",
|
||||
"key": "{$1}CPU",
|
||||
"keyColor": "38;5;75",
|
||||
"type": "cpu"
|
||||
},
|
||||
{
|
||||
"key": "██ Memory",
|
||||
"key": "{$1}Memory",
|
||||
"keyColor": "38;5;123",
|
||||
"type": "memory"
|
||||
}
|
||||
|
@ -12,7 +12,10 @@
|
||||
"color": {
|
||||
"separator": "blue"
|
||||
},
|
||||
"separator": " | "
|
||||
"separator": " | ",
|
||||
"constants": [
|
||||
">-----------<+>---------------------------------------------<"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
@ -22,7 +25,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": ">-----------<+>------------------------------------------<",
|
||||
"format": "{$1}",
|
||||
"outputColor": "separator"
|
||||
},
|
||||
{
|
||||
@ -57,7 +60,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": ">-----------<+>------------------------------------------<",
|
||||
"format": "{$1}",
|
||||
"outputColor": "separator"
|
||||
},
|
||||
{
|
||||
@ -97,7 +100,7 @@
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": ">-----------<+>------------------------------------------<",
|
||||
"format": "{$1}",
|
||||
"outputColor": "separator"
|
||||
},
|
||||
"break",
|
||||
|
@ -2,9 +2,13 @@
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": "debian_small",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"binaryPrefix": "si"
|
||||
"size": {
|
||||
"binaryPrefix": "si"
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
"vulkan",
|
||||
|
@ -3,13 +3,15 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"source": "arch_small",
|
||||
"type": "small",
|
||||
"padding": {
|
||||
"right": 1
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"binaryPrefix": "si",
|
||||
"size": {
|
||||
"binaryPrefix": "si"
|
||||
},
|
||||
"color": "blue",
|
||||
"separator": " "
|
||||
},
|
||||
|
@ -4,7 +4,7 @@
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": null,
|
||||
"display": {
|
||||
"color": "reset_magenta"
|
||||
"color": "magenta"
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
|
@ -3,12 +3,6 @@
|
||||
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
// "logo": {
|
||||
// "type": "iterm",
|
||||
// "source": "/Users/carter/Desktop/apple1.png",
|
||||
// "width": 28,
|
||||
// "height": 12
|
||||
// },
|
||||
"display": {
|
||||
"separator": " "
|
||||
},
|
||||
@ -125,8 +119,8 @@
|
||||
"key": "╰─",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
|
||||
"break",
|
||||
|
||||
{
|
||||
"type": "title",
|
||||
"key": "╭─",
|
||||
|
@ -244,6 +244,27 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
//test for constant, if so evaluate it
|
||||
if (firstChar == '$')
|
||||
{
|
||||
char* pend = NULL;
|
||||
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
|
||||
uint32_t index = (uint32_t) indexSigned;
|
||||
bool backward = indexSigned < 0;
|
||||
|
||||
if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index)
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward
|
||||
? instance.config.display.constants.length - index
|
||||
: index - 1);
|
||||
ffStrbufAppend(buffer, item);
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t truncLength = INT32_MAX;
|
||||
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
|
||||
if (pColon != NULL)
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
typedef enum FFformatargtype
|
||||
{
|
||||
FF_FORMAT_ARG_TYPE_NULL = 0,
|
||||
|
@ -229,7 +229,6 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
||||
hOutput = hConout;
|
||||
}
|
||||
WriteFile(hOutput, "TEST\n", 5, &bytes, NULL);
|
||||
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL);
|
||||
}
|
||||
|
||||
|
@ -79,15 +79,15 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
||||
{
|
||||
switch (instance.config.display.binaryPrefixType)
|
||||
switch (instance.config.display.sizeBinaryPrefix)
|
||||
{
|
||||
case FF_BINARY_PREFIX_TYPE_IEC:
|
||||
case FF_SIZE_BINARY_PREFIX_TYPE_IEC:
|
||||
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
|
||||
break;
|
||||
case FF_BINARY_PREFIX_TYPE_SI:
|
||||
case FF_SIZE_BINARY_PREFIX_TYPE_SI:
|
||||
parseSize(result, bytes, 1000, (const char*[]) {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL});
|
||||
break;
|
||||
case FF_BINARY_PREFIX_TYPE_JEDEC:
|
||||
case FF_SIZE_BINARY_PREFIX_TYPE_JEDEC:
|
||||
parseSize(result, bytes, 1024, (const char*[]) {"B", "KB", "MB", "GB", "TB", NULL});
|
||||
break;
|
||||
default:
|
||||
@ -96,6 +96,20 @@ void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
||||
}
|
||||
}
|
||||
|
||||
bool ffParseFrequency(uint32_t mhz, FFstrbuf* result)
|
||||
{
|
||||
if (mhz == 0)
|
||||
return false;
|
||||
|
||||
int8_t ndigits = instance.config.display.freqNdigits;
|
||||
|
||||
if (ndigits >= 0)
|
||||
ffStrbufAppendF(result, "%.*f GHz", ndigits, mhz / 1000.);
|
||||
else
|
||||
ffStrbufAppendF(result, "%u MHz", (unsigned) mhz);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
|
||||
{
|
||||
if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0)
|
||||
|
@ -26,3 +26,4 @@ void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty);
|
||||
int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFstrbuf* result);
|
||||
bool ffParseFrequency(uint32_t mhz, FFstrbuf* result);
|
||||
|
@ -4,11 +4,12 @@
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef _WIN32
|
||||
#include "util/windows/getline.h"
|
||||
#endif
|
||||
|
||||
static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
|
||||
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
if(**line == '\0')
|
||||
return false;
|
||||
@ -32,7 +33,7 @@ static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf*
|
||||
}
|
||||
|
||||
//Line doesn't match start, skip it
|
||||
if(**line != *start || **line == '\0')
|
||||
if(tolower(**line) != tolower(*start) || **line == '\0')
|
||||
return false;
|
||||
|
||||
//Line and start match, continue testing
|
||||
@ -69,14 +70,9 @@ static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf*
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return parsePropLinePointer(&line, start, buffer);
|
||||
}
|
||||
|
||||
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
while(!parsePropLinePointer(&lines, start, buffer))
|
||||
while(!ffParsePropLinePointer(&lines, start, buffer))
|
||||
{
|
||||
while(*lines != '\0' && *lines != '\n')
|
||||
++lines;
|
||||
|
@ -8,12 +8,18 @@ typedef struct FFpropquery
|
||||
FFstrbuf* buffer;
|
||||
} FFpropquery;
|
||||
|
||||
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
|
||||
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer);
|
||||
|
||||
static inline bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropLinePointer(&line, start, buffer);
|
||||
}
|
||||
|
||||
static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
|
||||
|
@ -20,7 +20,7 @@ static inline uint64_t ffTimeGetTick() //In msec
|
||||
#else
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
|
||||
return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ static inline uint64_t ffTimeGetNow()
|
||||
#else
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_REALTIME, &timeNow);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
|
||||
return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -549,19 +549,6 @@
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "binary-prefix",
|
||||
"desc": "Set the binary prefix to used",
|
||||
"arg": {
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"IEC": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ...",
|
||||
"SI": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ...",
|
||||
"JEDEC": "1024 Bytes = 1 kB, 1024 kB = 1 MB, ..."
|
||||
},
|
||||
"default": "IEC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "percent-type",
|
||||
"desc": "Set the percentage output type",
|
||||
@ -669,6 +656,19 @@
|
||||
"type": "num"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "size-binary-prefix",
|
||||
"desc": "Set the binary prefix to used when formatting sizes",
|
||||
"arg": {
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"IEC": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ...",
|
||||
"SI": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ...",
|
||||
"JEDEC": "1024 Bytes = 1 kB, 1024 kB = 1 MB, ..."
|
||||
},
|
||||
"default": "IEC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "size-max-prefix",
|
||||
"desc": "Set the largest binary prefix to use when formatting sizes",
|
||||
@ -688,6 +688,14 @@
|
||||
"default": "YB"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "freq-ndigits",
|
||||
"desc": "Set the number of digits to keep after the decimal point when printing CPU / GPU frequency in GHz",
|
||||
"arg": {
|
||||
"type": "num",
|
||||
"default": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "temp-unit",
|
||||
"desc": "Set the unit of the temperature",
|
||||
@ -947,7 +955,7 @@
|
||||
},
|
||||
{
|
||||
"long": "separator-string",
|
||||
"desc": "Set the string printed by the separator module",
|
||||
"desc": "Set the string to be printed by the separator line",
|
||||
"arg": {
|
||||
"type": "str",
|
||||
"default": "-"
|
||||
@ -955,12 +963,21 @@
|
||||
},
|
||||
{
|
||||
"long": "separator-output-color",
|
||||
"desc": "Set the color of the separator module",
|
||||
"desc": "Set the color of the separator line",
|
||||
"arg": {
|
||||
"type": "color",
|
||||
"default": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "separator-length",
|
||||
"desc": "Set the length of the separator line",
|
||||
"remark": "Set to 0 to automatically calculate it with the title length",
|
||||
"arg": {
|
||||
"type": "num",
|
||||
"default": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "disk-folders",
|
||||
"desc": "A colon (semicolon on Windows) separated list of folder paths to be detected",
|
||||
@ -1168,14 +1185,6 @@
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "cpu-freq-ndigits",
|
||||
"desc": "Set the number of digits to keep after the decimal point when printing CPU frequency",
|
||||
"arg": {
|
||||
"type": "num",
|
||||
"default": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "cpu-show-pe-core-count",
|
||||
"desc": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
|
||||
@ -1538,13 +1547,14 @@
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"block": "\u2588\u2588\u2588",
|
||||
"background": "(whitespaces with background)",
|
||||
"circle": "\u25cf",
|
||||
"diamond": "\u25c6",
|
||||
"triangle": "\u25b2",
|
||||
"square": "\u25a0",
|
||||
"star": "\u2605"
|
||||
},
|
||||
"default": "block"
|
||||
"default": "background"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ static const char* detectWithBacklight(FFlist* result)
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(&backlightDir, entry->d_name);
|
||||
ffStrbufAppendS(&backlightDir, "/actual_brightness");
|
||||
ffStrbufAppendS(&backlightDir, "/brightness");
|
||||
if(ffReadFileBuffer(backlightDir.chars, &buffer))
|
||||
{
|
||||
double actualBrightness = ffStrbufToDouble(&buffer);
|
||||
|
@ -19,10 +19,9 @@ typedef struct FFCPUResult
|
||||
uint16_t coresLogical;
|
||||
uint16_t coresOnline;
|
||||
|
||||
double frequencyBase; // GHz
|
||||
double frequencyMax; // GHz
|
||||
double frequencyMin; // GHz
|
||||
double frequencyBiosLimit; // GHz
|
||||
uint32_t frequencyBase; // GHz
|
||||
uint32_t frequencyMax; // GHz
|
||||
uint32_t frequencyBiosLimit; // GHz
|
||||
|
||||
FFCPUCore coreTypes[16]; // number of P cores, E cores, etc.
|
||||
|
||||
|
@ -43,38 +43,37 @@ static const char* detectFrequency(FFCPUResult* cpu)
|
||||
if (!IOObjectConformsTo(entryDevice, "AppleARMIODevice"))
|
||||
return "\"pmgr\" should conform to \"AppleARMIODevice\"";
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
|
||||
if (IORegistryEntryCreateCFProperties(entryDevice, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
return "IORegistryEntryCreateCFProperties() failed";
|
||||
|
||||
uint32_t pMin, eMin, aMax, pCoreLength;
|
||||
if (ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), 0, 4, (uint8_t*) &pMin, &pCoreLength) != NULL) // pCore
|
||||
FF_CFTYPE_AUTO_RELEASE CFDataRef freqProperty = (CFDataRef) IORegistryEntryCreateCFProperty(entryDevice, CFSTR("voltage-states5-sram"), kCFAllocatorDefault, kNilOptions);
|
||||
if (CFGetTypeID(freqProperty) != CFDataGetTypeID())
|
||||
return "\"voltage-states5-sram\" in \"pmgr\" is not found";
|
||||
if (ffCfDictGetData(properties, CFSTR("voltage-states1-sram"), 0, 4, (uint8_t*) &eMin, NULL) != NULL) // eCore
|
||||
return "\"voltage-states1-sram\" in \"pmgr\" is not found";
|
||||
|
||||
cpu->frequencyMin = (pMin < eMin ? pMin : eMin) / (1000.0 * 1000 * 1000);
|
||||
// voltage-states5-sram stores supported <frequency / voltage> pairs of pcores from the lowest to the highest
|
||||
// voltage-states1-sram stores ecores'
|
||||
CFIndex propLength = CFDataGetLength(freqProperty);
|
||||
if (propLength == 0 || propLength % (CFIndex) sizeof(uint32_t) * 2 != 0)
|
||||
return "Invalid \"voltage-states5-sram\" length";
|
||||
|
||||
if (pCoreLength >= 8)
|
||||
{
|
||||
ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), pCoreLength - 8, 4, (uint8_t*) &aMax, NULL);
|
||||
cpu->frequencyMax = aMax / (1000.0 * 1000 * 1000);
|
||||
}
|
||||
uint32_t* pStart = (uint32_t*) CFDataGetBytePtr(freqProperty);
|
||||
uint32_t pMax = *pStart;
|
||||
for (CFIndex i = 2; i < propLength / (CFIndex) sizeof(uint32_t) && pStart[i] > 0; i += 2 /* skip voltage */)
|
||||
pMax = pMax > pStart[i] ? pMax : pStart[i];
|
||||
|
||||
if (pMax > 0)
|
||||
cpu->frequencyMax = pMax / 1000 / 1000;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static const char* detectFrequency(FFCPUResult* cpu)
|
||||
{
|
||||
cpu->frequencyBase = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0;
|
||||
cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0;
|
||||
cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0) / 1000.0 / 1000.0 / 1000.0;
|
||||
if(cpu->frequencyBase != cpu->frequencyBase)
|
||||
cpu->frequencyBase = (uint32_t) (ffSysctlGetInt64("hw.cpufrequency", 0) / 1000 / 1000);
|
||||
cpu->frequencyMax = (uint32_t) (ffSysctlGetInt64("hw.cpufrequency_max", 0) / 1000 / 1000);
|
||||
if(cpu->frequencyBase == 0)
|
||||
{
|
||||
unsigned current = 0;
|
||||
size_t size = sizeof(current);
|
||||
if (sysctl((int[]){ CTL_HW, HW_CPU_FREQ }, 2, ¤t, &size, NULL, 0) == 0)
|
||||
cpu->frequencyBase = (double) current / 1000.0 / 1000.0 / 1000.0;
|
||||
cpu->frequencyBase = (uint32_t) (current / 1000 / 1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -44,16 +44,13 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
ffStrbufClear(&buffer);
|
||||
char key[32];
|
||||
snprintf(key, sizeof(key), "dev.cpu.%u.freq_levels", i);
|
||||
if (ffSysctlGetString(key, &buffer) == NULL && buffer.length > 0)
|
||||
if (ffSysctlGetString(key, &buffer) == NULL)
|
||||
{
|
||||
if (buffer.length == 0) continue;
|
||||
|
||||
// MHz/Watts pairs like: 2501/32000 2187/27125 2000/24000
|
||||
uint32_t fmax = (uint32_t) strtoul(buffer.chars, NULL, 10);
|
||||
uint32_t fmin = fmax;
|
||||
uint32_t i = ffStrbufLastIndexC(&buffer, ' ');
|
||||
if (i < buffer.length)
|
||||
fmin = (uint32_t) strtoul(buffer.chars + i + 1, NULL, 10);
|
||||
if (!(cpu->frequencyMin <= fmin)) cpu->frequencyMin = fmin; // Counting for NaN
|
||||
if (!(cpu->frequencyMax >= fmax)) cpu->frequencyMax = fmax;
|
||||
if (cpu->frequencyMax < fmax) cpu->frequencyMax = fmax;
|
||||
|
||||
if (options->showPeCoreCount)
|
||||
{
|
||||
@ -65,12 +62,11 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
cpu->coreTypes[ifreq].count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
cpu->frequencyMin /= 1000;
|
||||
cpu->frequencyMax /= 1000;
|
||||
|
||||
int clockRate = ffSysctlGetInt("hw.clockrate", 0);
|
||||
cpu->frequencyBase = clockRate <= 0 ? 0.0/0.0 : clockRate / 1000.0;
|
||||
cpu->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (options->temp)
|
||||
|
@ -94,7 +94,7 @@ static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, co
|
||||
bool ok = ffReadFileBuffer(basePath->chars, buffer);
|
||||
ffStrbufSubstrBefore(basePath, baseLen);
|
||||
if (ok)
|
||||
return (uint32_t) ffStrbufToUInt(buffer, 0);
|
||||
return (uint32_t) (ffStrbufToUInt(buffer, 0) / 1000);
|
||||
|
||||
if (scalingFileName)
|
||||
{
|
||||
@ -102,7 +102,7 @@ static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, co
|
||||
ok = ffReadFileBuffer(basePath->chars, buffer);
|
||||
ffStrbufSubstrBefore(basePath, baseLen);
|
||||
if (ok)
|
||||
return (uint32_t) ffStrbufToUInt(buffer, 0);
|
||||
return (uint32_t) (ffStrbufToUInt(buffer, 0) / 1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -143,36 +143,15 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
|
||||
ffStrbufAppendS(&path, entry->d_name);
|
||||
uint32_t fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
|
||||
if (fbase > 0)
|
||||
{
|
||||
if (cpu->frequencyBase == cpu->frequencyBase)
|
||||
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
|
||||
else
|
||||
cpu->frequencyBase = fbase;
|
||||
}
|
||||
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
|
||||
|
||||
uint32_t fbioslimit = getFrequency(&path, "/bios_limit", NULL, &buffer);
|
||||
if (fbioslimit > 0)
|
||||
{
|
||||
if (cpu->frequencyBiosLimit == cpu->frequencyBiosLimit)
|
||||
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
|
||||
else
|
||||
cpu->frequencyBiosLimit = fbioslimit;
|
||||
}
|
||||
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
|
||||
|
||||
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
|
||||
if (fmax > 0)
|
||||
{
|
||||
if (cpu->frequencyMax == cpu->frequencyMax)
|
||||
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
|
||||
else
|
||||
cpu->frequencyMax = fmax;
|
||||
}
|
||||
uint32_t fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
|
||||
if (fmin > 0)
|
||||
{
|
||||
if (cpu->frequencyMin == cpu->frequencyMin)
|
||||
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
|
||||
else
|
||||
cpu->frequencyMin = fmin;
|
||||
}
|
||||
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
|
||||
|
||||
if (options->showPeCoreCount)
|
||||
{
|
||||
@ -187,10 +166,6 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
|
||||
ffStrbufSubstrBefore(&path, baseLen);
|
||||
}
|
||||
}
|
||||
cpu->frequencyBase /= 1e6;
|
||||
cpu->frequencyMax /= 1e6;
|
||||
cpu->frequencyMin /= 1e6;
|
||||
cpu->frequencyBiosLimit /= 1e6;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -272,8 +247,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
|
||||
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase != cpu->frequencyBase)
|
||||
cpu->frequencyBase = ffStrbufToDouble(&cpuMHz) / 1000;
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
if(cpuUarch.length > 0)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
cpu->frequencyBase = kn->value.ui32 / 1000.;
|
||||
cpu->frequencyBase = kn->value.ui32;
|
||||
}
|
||||
|
||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||
|
@ -65,8 +65,8 @@ inline static const char* detectSpeedByCpuid(FFCPUResult* cpu)
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base / 1000.0;
|
||||
if (max) cpu->frequencyMax = max / 1000.0;
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
|
||||
return "No active CPU is found in SMBIOS data";
|
||||
}
|
||||
|
||||
double speed = data->MaxSpeed / 1000.0;
|
||||
uint32_t speed = data->MaxSpeed;
|
||||
// Sometimes SMBIOS reports invalid value. We assume that max speed is small than 2x of base
|
||||
if (speed < cpu->frequencyBase || speed > cpu->frequencyBase * 2)
|
||||
return "Possible invalid CPU max speed in SMBIOS data. See #800";
|
||||
@ -159,7 +159,7 @@ static const char* detectByRegistry(FFCPUResult* cpu)
|
||||
|
||||
uint32_t mhz;
|
||||
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
|
||||
cpu->frequencyBase = mhz / 1000.0;
|
||||
cpu->frequencyBase = mhz;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -180,8 +180,8 @@ static const char* detectCoreTypes(FFCPUResult* cpu)
|
||||
++cpu->coreTypes[ifreq].count;
|
||||
}
|
||||
|
||||
if (cpu->frequencyBase != cpu->frequencyBase)
|
||||
cpu->frequencyBase = pinfo->MaxMhz / 1000.0;
|
||||
if (cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = pinfo->MaxMhz;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
detectSpeedByCpuid(cpu);
|
||||
if (options->showPeCoreCount) detectCoreTypes(cpu);
|
||||
|
||||
if (cpu->frequencyMax != cpu->frequencyMax)
|
||||
if (cpu->frequencyMax == 0)
|
||||
detectMaxSpeedBySmbios(cpu);
|
||||
|
||||
if(options->temp)
|
||||
|
@ -71,6 +71,10 @@ static bool isPhysicalDevice(const struct mntent* device)
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "fd") //Ignore fd devices
|
||||
) return false;
|
||||
|
||||
// https://source.android.com/docs/core/ota/apex?hl=zh-cn
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
return false;
|
||||
|
||||
#endif // __ANDROID__
|
||||
|
||||
return true;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "displayserver.h"
|
||||
|
||||
bool ffdsAppendDisplay(
|
||||
FFDisplayResult* ffdsAppendDisplay(
|
||||
FFDisplayServerResult* result,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
@ -11,10 +11,12 @@ bool ffdsAppendDisplay(
|
||||
FFstrbuf* name,
|
||||
FFDisplayType type,
|
||||
bool primary,
|
||||
uint64_t id)
|
||||
uint64_t id,
|
||||
uint32_t physicalWidth,
|
||||
uint32_t physicalHeight)
|
||||
{
|
||||
if(width == 0 || height == 0)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
FFDisplayResult* display = ffListAdd(&result->displays);
|
||||
display->width = width;
|
||||
@ -25,10 +27,16 @@ bool ffdsAppendDisplay(
|
||||
display->rotation = rotation;
|
||||
ffStrbufInitMove(&display->name, name);
|
||||
display->type = type;
|
||||
display->primary = primary;
|
||||
display->id = id;
|
||||
display->physicalWidth = physicalWidth;
|
||||
display->physicalHeight = physicalHeight;
|
||||
display->primary = primary;
|
||||
|
||||
return true;
|
||||
display->bitDepth = 0;
|
||||
display->hdrEnabled = false;
|
||||
display->wcgEnabled = false;
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds);
|
||||
|
@ -58,8 +58,13 @@ typedef struct FFDisplayResult
|
||||
FFstrbuf name;
|
||||
FFDisplayType type;
|
||||
uint32_t rotation;
|
||||
bool primary;
|
||||
uint64_t id; // platform dependent
|
||||
uint32_t physicalWidth;
|
||||
uint32_t physicalHeight;
|
||||
bool primary;
|
||||
uint8_t bitDepth;
|
||||
bool hdrEnabled;
|
||||
bool wcgEnabled;
|
||||
} FFDisplayResult;
|
||||
|
||||
typedef struct FFDisplayServerResult
|
||||
@ -74,7 +79,7 @@ typedef struct FFDisplayServerResult
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer();
|
||||
|
||||
bool ffdsAppendDisplay(
|
||||
FFDisplayResult* ffdsAppendDisplay(
|
||||
FFDisplayServerResult* result,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
@ -85,4 +90,6 @@ bool ffdsAppendDisplay(
|
||||
FFstrbuf* name,
|
||||
FFDisplayType type,
|
||||
bool primary,
|
||||
uint64_t id);
|
||||
uint64_t id,
|
||||
uint32_t physicalWidth,
|
||||
uint32_t physicalHeight);
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include "displayserver.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
#include "common/processing.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
@ -63,6 +64,8 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
@ -83,6 +86,8 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
||||
uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
ffStrbufSubstrAfterFirstC(&buffer, ',');
|
||||
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
ffStrbufSubstrAfterFirstC(&buffer, ',');
|
||||
uint32_t ppi = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
return ffdsAppendDisplay(ds,
|
||||
width,
|
||||
height,
|
||||
@ -93,7 +98,9 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
||||
0,
|
||||
FF_DISPLAY_TYPE_BUILTIN,
|
||||
false,
|
||||
0
|
||||
0,
|
||||
(uint32_t) (width / ppi * 25.4),
|
||||
(uint32_t) (height / ppi * 25.4)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "displayserver.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -57,7 +58,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
if(CoreDisplay_IODisplayCreateInfoDictionary)
|
||||
{
|
||||
io_service_t servicePort = CGDisplayIOServicePort(screen);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
@ -67,7 +68,9 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
}
|
||||
#endif
|
||||
|
||||
ffdsAppendDisplay(ds,
|
||||
CGSize size = CGDisplayScreenSize(screen);
|
||||
|
||||
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||
(uint32_t)CGDisplayModeGetPixelWidth(mode),
|
||||
(uint32_t)CGDisplayModeGetPixelHeight(mode),
|
||||
refreshRate,
|
||||
@ -77,8 +80,28 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
&name,
|
||||
CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL,
|
||||
CGDisplayIsMain(screen),
|
||||
(uint64_t)screen
|
||||
(uint64_t)screen,
|
||||
(uint32_t) (size.width + 0.5),
|
||||
(uint32_t) (size.height + 0.5)
|
||||
);
|
||||
if (display)
|
||||
{
|
||||
// Shitty code
|
||||
uint8_t bitDepth = 0;
|
||||
FF_CFTYPE_AUTO_RELEASE CFStringRef desc = CFCopyDescription(mode);
|
||||
CFRange start = CFStringFind(desc, CFSTR("BitsPerSample = "), 0);
|
||||
if (start.location != kCFNotFound)
|
||||
{
|
||||
for (CFIndex idx = start.location + start.length; idx < CFStringGetLength(desc); ++idx)
|
||||
{
|
||||
UniChar ch = CFStringGetCharacterAtIndex(desc, idx);
|
||||
if (!ffCharIsDigit((char) ch))
|
||||
break;
|
||||
bitDepth = (uint8_t) (bitDepth * 10 + (ch - '0'));
|
||||
}
|
||||
}
|
||||
display->bitDepth = bitDepth;
|
||||
}
|
||||
CGDisplayModeRelease(mode);
|
||||
}
|
||||
CGDisplayRelease(screen);
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "displayserver.h"
|
||||
#include "detection/os/os.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/edidHelper.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <WinUser.h>
|
||||
@ -73,6 +76,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
if (!monitorInfo) continue;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
uint32_t physicalWidth = 0, physicalHeight = 0;
|
||||
|
||||
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {
|
||||
.header = {
|
||||
@ -84,13 +88,39 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
};
|
||||
if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS)
|
||||
{
|
||||
if (targetName.flags.friendlyNameFromEdid)
|
||||
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
|
||||
wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
|
||||
wchar_t* pRegPath = regPath + strlen("SYSTEM\\CurrentControlSet\\Enum");
|
||||
wchar_t* pDevPath = targetName.monitorDevicePath + strlen("\\\\?");
|
||||
while (*pDevPath && *pDevPath != L'{')
|
||||
{
|
||||
if (*pDevPath == L'#')
|
||||
*pRegPath = L'\\';
|
||||
else
|
||||
*pRegPath = *pDevPath;
|
||||
++pRegPath;
|
||||
++pDevPath;
|
||||
assert(pRegPath < regPath + sizeof(regPath) / sizeof(wchar_t) + strlen("Device Parameters"));
|
||||
}
|
||||
wcscpy(pRegPath, L"Device Parameters");
|
||||
|
||||
uint8_t edidData[1024];
|
||||
DWORD edidLength = sizeof(edidData);
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, regPath, L"EDID", RRF_RT_REG_BINARY, NULL, edidData, &edidLength) == ERROR_SUCCESS &&
|
||||
edidLength > 0 && edidLength % 128 == 0)
|
||||
{
|
||||
ffEdidGetName(edidData, &name);
|
||||
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufSetWS(&name, targetName.monitorDevicePath);
|
||||
ffStrbufSubstrAfterFirstC(&name, '#');
|
||||
ffStrbufSubstrBeforeFirstC(&name, '#');
|
||||
if (targetName.flags.friendlyNameFromEdid)
|
||||
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
|
||||
else
|
||||
{
|
||||
ffStrbufSetWS(&name, targetName.monitorDevicePath);
|
||||
ffStrbufSubstrAfterFirstC(&name, '#');
|
||||
ffStrbufSubstrBeforeFirstC(&name, '#');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,26 +132,21 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
uint32_t temp = width;
|
||||
width = height;
|
||||
height = temp;
|
||||
temp = physicalWidth;
|
||||
physicalWidth = physicalHeight;
|
||||
physicalHeight = temp;
|
||||
}
|
||||
|
||||
uint32_t rotation;
|
||||
switch (path->targetInfo.rotation)
|
||||
{
|
||||
case DISPLAYCONFIG_ROTATION_ROTATE90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case DISPLAYCONFIG_ROTATION_ROTATE180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case DISPLAYCONFIG_ROTATION_ROTATE270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
case DISPLAYCONFIG_ROTATION_ROTATE90: rotation = 90; break;
|
||||
case DISPLAYCONFIG_ROTATION_ROTATE180: rotation = 180; break;
|
||||
case DISPLAYCONFIG_ROTATION_ROTATE270: rotation = 270; break;
|
||||
default: rotation = 0; break;
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(ds,
|
||||
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||
width,
|
||||
height,
|
||||
path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator,
|
||||
@ -135,8 +160,28 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED
|
||||
? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL,
|
||||
!!(monitorInfo->info.dwFlags & MONITORINFOF_PRIMARY),
|
||||
(uint64_t)(uintptr_t) monitorInfo->handle
|
||||
(uint64_t)(uintptr_t) monitorInfo->handle,
|
||||
physicalWidth,
|
||||
physicalHeight
|
||||
);
|
||||
|
||||
if (display)
|
||||
{
|
||||
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
|
||||
.header = {
|
||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
|
||||
.size = sizeof(advColorInfo),
|
||||
.adapterId = path->targetInfo.adapterId,
|
||||
.id = path->targetInfo.id,
|
||||
}
|
||||
};
|
||||
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
|
||||
{
|
||||
display->hdrEnabled = !!advColorInfo.advancedColorEnabled;
|
||||
display->wcgEnabled = !!advColorInfo.wideColorEnforced;
|
||||
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
if (ffSettingsGetFreeBSDKenv("screen.height", &buf))
|
||||
{
|
||||
uint32_t height = (uint32_t) ffStrbufToUInt(&buf, 0);
|
||||
ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0);
|
||||
ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName)
|
||||
// However I can't find a better method to get the edid data
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
DIR* dirp = opendir(drmDirPath);
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
|
||||
if(dirp == NULL)
|
||||
return false;
|
||||
|
||||
@ -90,13 +90,25 @@ bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName)
|
||||
{
|
||||
ffStrbufClear(edidName);
|
||||
ffEdidGetName(edidData, edidName);
|
||||
closedir(dirp);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ffStrbufClear(edidName);
|
||||
closedir(dirp);
|
||||
return false;
|
||||
}
|
||||
|
||||
FFDisplayType ffdsGetDisplayType(const char* name)
|
||||
{
|
||||
if(ffStrStartsWith(name, "eDP-") || ffStrStartsWith(name, "LVDS-"))
|
||||
return FF_DISPLAY_TYPE_BUILTIN;
|
||||
else if(ffStrStartsWith(name, "HDMI-") ||
|
||||
ffStrStartsWith(name, "DP-") ||
|
||||
ffStrStartsWith(name, "DisplayPort-") ||
|
||||
ffStrStartsWith(name, "DVI-") ||
|
||||
ffStrStartsWith(name, "VGA-"))
|
||||
return FF_DISPLAY_TYPE_EXTERNAL;
|
||||
|
||||
return FF_DISPLAY_TYPE_UNKNOWN;
|
||||
}
|
||||
|
@ -20,4 +20,6 @@ void ffdsConnectDrm(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsDetectWMDE(FFDisplayServerResult* result);
|
||||
|
||||
FFDisplayType ffdsGetDisplayType(const char* drmConnectorName);
|
||||
|
||||
#endif
|
||||
|
@ -37,7 +37,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned width = 0, height = 0;
|
||||
unsigned width = 0, height = 0, physicalWidth = 0, physicalHeight = 0;
|
||||
double refreshRate = 0;
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
@ -49,6 +49,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
{
|
||||
ffEdidGetName(edidData, &name);
|
||||
ffEdidGetPreferredResolutionAndRefreshRate(edidData, &width, &height, &refreshRate);
|
||||
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -78,7 +79,9 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
0,
|
||||
physicalWidth,
|
||||
physicalHeight
|
||||
);
|
||||
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
@ -339,12 +342,14 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
0,
|
||||
0,
|
||||
&name,
|
||||
conn->connector_type == DRM_MODE_CONNECTOR_eDP
|
||||
conn->connector_type == DRM_MODE_CONNECTOR_eDP || conn->connector_type == DRM_MODE_CONNECTOR_LVDS
|
||||
? FF_DISPLAY_TYPE_BUILTIN
|
||||
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB
|
||||
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB || conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort
|
||||
? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
conn->connector_id
|
||||
conn->connector_id,
|
||||
conn->mmWidth,
|
||||
conn->mmHeight
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -25,14 +25,16 @@ static void waylandOutputGeometryListener(void *data,
|
||||
FF_MAYBE_UNUSED struct wl_output *output,
|
||||
FF_MAYBE_UNUSED int32_t x,
|
||||
FF_MAYBE_UNUSED int32_t y,
|
||||
FF_MAYBE_UNUSED int32_t physical_width,
|
||||
FF_MAYBE_UNUSED int32_t physical_height,
|
||||
int32_t physical_width,
|
||||
int32_t physical_height,
|
||||
FF_MAYBE_UNUSED int32_t subpixel,
|
||||
FF_MAYBE_UNUSED const char *make,
|
||||
FF_MAYBE_UNUSED const char *model,
|
||||
int32_t transform)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->physicalWidth = physical_width;
|
||||
display->physicalHeight = physical_height;
|
||||
display->transform = (enum wl_output_transform) transform;
|
||||
}
|
||||
|
||||
@ -108,38 +110,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
if(display.width <= 0 || display.height <= 0)
|
||||
return;
|
||||
|
||||
uint32_t rotation;
|
||||
switch(display.transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rotation)
|
||||
{
|
||||
case 90:
|
||||
case 270: {
|
||||
int32_t temp = display.width;
|
||||
display.width = display.height;
|
||||
display.height = temp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint32_t rotation = ffWaylandHandleRotation(&display);
|
||||
|
||||
ffdsAppendDisplay(wldata->result,
|
||||
(uint32_t) display.width,
|
||||
@ -156,7 +127,9 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
: &display.name,
|
||||
display.type,
|
||||
false,
|
||||
display.id
|
||||
display.id,
|
||||
(uint32_t) display.physicalWidth,
|
||||
(uint32_t) display.physicalHeight
|
||||
);
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
|
@ -92,28 +92,39 @@ static void waylandKdeGeometryListener(void *data,
|
||||
FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2,
|
||||
FF_MAYBE_UNUSED int32_t x,
|
||||
FF_MAYBE_UNUSED int32_t y,
|
||||
FF_MAYBE_UNUSED int32_t physical_width,
|
||||
FF_MAYBE_UNUSED int32_t physical_height,
|
||||
int32_t physical_width,
|
||||
int32_t physical_height,
|
||||
FF_MAYBE_UNUSED int32_t subpixel,
|
||||
FF_MAYBE_UNUSED const char *make,
|
||||
FF_MAYBE_UNUSED const char *model,
|
||||
int32_t transform)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->physicalWidth = physical_width;
|
||||
display->physicalHeight = physical_height;
|
||||
display->transform = (enum wl_output_transform) transform;
|
||||
}
|
||||
|
||||
void waylandOutputNameListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* output, const char *name)
|
||||
static void waylandKdeNameListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* kde_output_device_v2, const char *name)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
if(ffStrStartsWith(name, "eDP-"))
|
||||
display->type = FF_DISPLAY_TYPE_BUILTIN;
|
||||
else if(ffStrStartsWith(name, "HDMI-"))
|
||||
display->type = FF_DISPLAY_TYPE_EXTERNAL;
|
||||
display->type = ffdsGetDisplayType(name);
|
||||
strncpy((char*) &display->id, name, sizeof(display->id));
|
||||
ffStrbufAppendS(&display->name, name);
|
||||
}
|
||||
|
||||
static void waylandKdeHdrListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, uint32_t hdr_enabled)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->hdrEnabled = !!hdr_enabled;
|
||||
}
|
||||
|
||||
static void waylandKdeWcgListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, uint32_t wcg_enabled)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->wcgEnabled = !!wcg_enabled;
|
||||
}
|
||||
|
||||
static struct kde_output_device_v2_listener outputListener = {
|
||||
.geometry = waylandKdeGeometryListener,
|
||||
.current_mode = waylandKdeCurrentModeListener,
|
||||
@ -129,10 +140,10 @@ static struct kde_output_device_v2_listener outputListener = {
|
||||
.overscan = (void*) stubListener,
|
||||
.vrr_policy = (void*) stubListener,
|
||||
.rgb_range = (void*) stubListener,
|
||||
.name = waylandOutputNameListener,
|
||||
.high_dynamic_range = (void*) stubListener,
|
||||
.name = waylandKdeNameListener,
|
||||
.high_dynamic_range = waylandKdeHdrListener,
|
||||
.sdr_brightness = (void*) stubListener,
|
||||
.wide_color_gamut = (void*) stubListener,
|
||||
.wide_color_gamut = waylandKdeWcgListener,
|
||||
.auto_rotate_policy = (void*) stubListener,
|
||||
.icc_profile_path = (void*) stubListener,
|
||||
.brightness_metadata = (void*) stubListener,
|
||||
@ -170,40 +181,9 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
|
||||
if(display.width <= 0 || display.height <= 0 || !display.internal)
|
||||
return;
|
||||
|
||||
uint32_t rotation;
|
||||
switch(display.transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
uint32_t rotation = ffWaylandHandleRotation(&display);
|
||||
|
||||
switch(rotation)
|
||||
{
|
||||
case 90:
|
||||
case 270: {
|
||||
int32_t temp = display.width;
|
||||
display.width = display.height;
|
||||
display.height = temp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(wldata->result,
|
||||
FFDisplayResult* item = ffdsAppendDisplay(wldata->result,
|
||||
(uint32_t) display.width,
|
||||
(uint32_t) display.height,
|
||||
display.refreshRate / 1000.0,
|
||||
@ -215,8 +195,15 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
|
||||
: &display.name,
|
||||
display.type,
|
||||
false,
|
||||
display.id
|
||||
display.id,
|
||||
(uint32_t) display.physicalWidth,
|
||||
(uint32_t) display.physicalHeight
|
||||
);
|
||||
if (item)
|
||||
{
|
||||
item->hdrEnabled = display.hdrEnabled;
|
||||
item->wcgEnabled = display.wcgEnabled;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
ffStrbufDestroy(&display.name);
|
||||
|
@ -201,10 +201,7 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const
|
||||
WaylandDisplay* display = data;
|
||||
if (display->id) return;
|
||||
|
||||
if(ffStrStartsWith(name, "eDP-"))
|
||||
display->type = FF_DISPLAY_TYPE_BUILTIN;
|
||||
else if(ffStrStartsWith(name, "HDMI-"))
|
||||
display->type = FF_DISPLAY_TYPE_EXTERNAL;
|
||||
display->type = ffdsGetDisplayType(name);
|
||||
if (!display->edidName.length)
|
||||
ffdsMatchDrmConnector(name, &display->edidName);
|
||||
display->id = ffWaylandGenerateIdFromName(name);
|
||||
@ -220,6 +217,47 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output
|
||||
if (!ffStrEquals(description, "Unknown Display") && !ffStrContains(description, "(null)"))
|
||||
ffStrbufAppendS(&display->description, description);
|
||||
}
|
||||
|
||||
uint32_t ffWaylandHandleRotation(WaylandDisplay* display)
|
||||
{
|
||||
uint32_t rotation;
|
||||
switch(display->transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rotation)
|
||||
{
|
||||
case 90:
|
||||
case 270: {
|
||||
int32_t temp = display->width;
|
||||
display->width = display->height;
|
||||
display->height = temp;
|
||||
|
||||
temp = display->physicalWidth;
|
||||
display->physicalWidth = display->physicalHeight;
|
||||
display->physicalHeight = temp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rotation;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ffdsConnectWayland(FFDisplayServerResult* result)
|
||||
|
@ -36,6 +36,8 @@ typedef struct WaylandDisplay
|
||||
WaylandData* parent;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t physicalWidth;
|
||||
int32_t physicalHeight;
|
||||
int32_t refreshRate;
|
||||
double scale;
|
||||
enum wl_output_transform transform;
|
||||
@ -44,6 +46,8 @@ typedef struct WaylandDisplay
|
||||
FFstrbuf description;
|
||||
FFstrbuf edidName;
|
||||
uint64_t id;
|
||||
bool hdrEnabled;
|
||||
bool wcgEnabled;
|
||||
void* internal;
|
||||
} WaylandDisplay;
|
||||
|
||||
@ -65,6 +69,8 @@ inline static uint64_t ffWaylandGenerateIdFromName(const char* name)
|
||||
|
||||
void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const char *name);
|
||||
void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output, const char* description);
|
||||
// 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);
|
||||
|
@ -71,10 +71,17 @@ static void waylandZwlrCurrentModeListener(void* data, FF_MAYBE_UNUSED struct zw
|
||||
wldata->refreshRate = current->refreshRate;
|
||||
}
|
||||
|
||||
static void waylandZwlrPhysicalSizeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, int32_t width, int32_t height)
|
||||
{
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
wldata->physicalWidth = width;
|
||||
wldata->physicalHeight = height;
|
||||
}
|
||||
|
||||
static const struct zwlr_output_head_v1_listener headListener = {
|
||||
.name = (void*) ffWaylandOutputNameListener,
|
||||
.description = (void*) ffWaylandOutputDescriptionListener,
|
||||
.physical_size = (void*) stubListener,
|
||||
.physical_size = waylandZwlrPhysicalSizeListener,
|
||||
.mode = waylandZwlrModeListener,
|
||||
.enabled = (void*) stubListener,
|
||||
.current_mode = waylandZwlrCurrentModeListener,
|
||||
@ -113,38 +120,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
|
||||
if(display.width <= 0 || display.height <= 0)
|
||||
return;
|
||||
|
||||
uint32_t rotation;
|
||||
switch(display.transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rotation)
|
||||
{
|
||||
case 90:
|
||||
case 270: {
|
||||
int32_t temp = display.width;
|
||||
display.width = display.height;
|
||||
display.height = temp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint32_t rotation = ffWaylandHandleRotation(&display);
|
||||
|
||||
ffdsAppendDisplay(wldata->result,
|
||||
(uint32_t) display.width,
|
||||
@ -160,7 +136,9 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
|
||||
: &display.name,
|
||||
display.type,
|
||||
false,
|
||||
display.id
|
||||
display.id,
|
||||
(uint32_t) display.physicalWidth,
|
||||
(uint32_t) display.physicalHeight
|
||||
);
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
|
@ -41,32 +41,25 @@ static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyDa
|
||||
static void* xcbGetProperty(XcbPropertyData* data, xcb_connection_t* connection, xcb_window_t window, const char* request)
|
||||
{
|
||||
xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(connection, true, (uint16_t) strlen(request), request);
|
||||
xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(connection, requestAtomCookie, NULL);
|
||||
FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(connection, requestAtomCookie, NULL);
|
||||
if(requestAtomReply == NULL)
|
||||
return NULL;
|
||||
|
||||
xcb_get_property_cookie_t propertyCookie = data->ffxcb_get_property(connection, false, window, requestAtomReply->atom, XCB_ATOM_ANY, 0, 64);
|
||||
|
||||
free(requestAtomReply);
|
||||
|
||||
xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL);
|
||||
FF_AUTO_FREE xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL);
|
||||
if(propertyReply == NULL)
|
||||
return NULL;
|
||||
|
||||
int length = data->ffxcb_get_property_value_length(propertyReply);
|
||||
if(length <= 0)
|
||||
{
|
||||
free(propertyReply);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Why are xcb property strings not null terminated???
|
||||
void* replyValue = malloc((size_t)length + 1);
|
||||
memcpy(replyValue, data->ffxcb_get_property_value(propertyReply), (size_t) length);
|
||||
((char*) replyValue)[length] = '\0';
|
||||
|
||||
free(propertyReply);
|
||||
|
||||
return replyValue;
|
||||
}
|
||||
|
||||
@ -75,28 +68,18 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
|
||||
if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0)
|
||||
return;
|
||||
|
||||
xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, connection, rootWindow, "_NET_SUPPORTING_WM_CHECK");
|
||||
FF_AUTO_FREE xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, connection, rootWindow, "_NET_SUPPORTING_WM_CHECK");
|
||||
if(wmWindow == NULL)
|
||||
return;
|
||||
|
||||
char* wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "_NET_WM_NAME");
|
||||
FF_AUTO_FREE char* wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "_NET_WM_NAME");
|
||||
if(wmName == NULL)
|
||||
wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "WM_NAME");
|
||||
|
||||
free(wmWindow);
|
||||
|
||||
if(wmName == NULL)
|
||||
if(wmName == NULL || *wmName == '\0')
|
||||
return;
|
||||
|
||||
if(*wmName == '\0')
|
||||
{
|
||||
free(wmName);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufSetS(&result->wmProcessName, wmName);
|
||||
|
||||
free(wmName);
|
||||
}
|
||||
|
||||
void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
@ -122,17 +105,20 @@ void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
|
||||
while(iterator.rem > 0)
|
||||
{
|
||||
xcb_screen_t* screen = iterator.data;
|
||||
ffdsAppendDisplay(result,
|
||||
(uint32_t) iterator.data->width_in_pixels,
|
||||
(uint32_t) iterator.data->height_in_pixels,
|
||||
(uint32_t) screen->width_in_pixels,
|
||||
(uint32_t) screen->height_in_pixels,
|
||||
0,
|
||||
(uint32_t) iterator.data->width_in_pixels,
|
||||
(uint32_t) iterator.data->height_in_pixels,
|
||||
(uint32_t) screen->width_in_pixels,
|
||||
(uint32_t) screen->height_in_pixels,
|
||||
0,
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
0,
|
||||
(uint32_t) screen->width_in_millimeters,
|
||||
(uint32_t) screen->height_in_millimeters
|
||||
);
|
||||
ffxcb_screen_next(&iterator);
|
||||
}
|
||||
@ -191,7 +177,7 @@ typedef struct XcbRandrData
|
||||
xcb_randr_get_screen_resources_current_reply_t* screenResources;
|
||||
} XcbRandrData;
|
||||
|
||||
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary)
|
||||
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
|
||||
{
|
||||
double refreshRate = (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
|
||||
|
||||
@ -204,13 +190,15 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo
|
||||
(uint32_t) modeInfo->height,
|
||||
rotation,
|
||||
name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
displayType,
|
||||
primary,
|
||||
0
|
||||
0,
|
||||
(uint32_t) output->mm_width,
|
||||
(uint32_t) output->mm_height
|
||||
);
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary)
|
||||
static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
|
||||
{
|
||||
//We do the check here, because we want the best fallback display if this call failed
|
||||
if(data->screenResources == NULL)
|
||||
@ -221,7 +209,7 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb
|
||||
while(modesIterator.rem > 0)
|
||||
{
|
||||
if(modesIterator.data->id == mode)
|
||||
return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary);
|
||||
return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary, output, displayType);
|
||||
|
||||
data->ffxcb_randr_mode_info_next(&modesIterator);
|
||||
}
|
||||
@ -229,10 +217,10 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary)
|
||||
static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
|
||||
{
|
||||
xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, crtc, XCB_CURRENT_TIME);
|
||||
xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL);
|
||||
FF_AUTO_FREE xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL);
|
||||
if(crtcInfoReply == NULL)
|
||||
return false;
|
||||
|
||||
@ -252,8 +240,8 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary);
|
||||
res = res ? true : ffdsAppendDisplay(
|
||||
bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary, output, displayType);
|
||||
res = res ? true : !!ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) crtcInfoReply->width,
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
@ -262,16 +250,17 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
rotation,
|
||||
name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
displayType,
|
||||
primary,
|
||||
0
|
||||
0,
|
||||
(uint32_t) output->mm_width,
|
||||
(uint32_t) output->mm_height
|
||||
);
|
||||
|
||||
free(crtcInfoReply);
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary)
|
||||
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType)
|
||||
{
|
||||
xcb_randr_get_output_info_cookie_t outputInfoCookie = data->ffxcb_randr_get_output_info(data->connection, output, XCB_CURRENT_TIME);
|
||||
FF_AUTO_FREE xcb_randr_get_output_info_reply_t* outputInfoReply = data->ffxcb_randr_get_output_info_reply(data->connection, outputInfoCookie, NULL);
|
||||
@ -294,7 +283,7 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
|
||||
}
|
||||
}
|
||||
|
||||
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary);
|
||||
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary, outputInfoReply, displayType);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -317,17 +306,18 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
|
||||
(uint32_t) data->propData.ffxcb_get_atom_name_name_length(nameReply),
|
||||
data->propData.ffxcb_get_atom_name_name(nameReply)
|
||||
);
|
||||
const FFDisplayType displayType = ffdsGetDisplayType(name.chars);
|
||||
|
||||
bool foundOutput = false;
|
||||
|
||||
while(outputIterator.rem > 0)
|
||||
{
|
||||
if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary))
|
||||
if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary, displayType))
|
||||
foundOutput = true;
|
||||
data->ffxcb_randr_output_next(&outputIterator);
|
||||
};
|
||||
|
||||
return foundOutput ? true : ffdsAppendDisplay(
|
||||
return foundOutput ? true : !!ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) monitor->width,
|
||||
(uint32_t) monitor->height,
|
||||
@ -336,16 +326,18 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
|
||||
(uint32_t) monitor->height,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
displayType,
|
||||
!!monitor->primary,
|
||||
0
|
||||
0,
|
||||
(uint32_t) monitor->width_in_millimeters,
|
||||
(uint32_t) monitor->height_in_millimeters
|
||||
);
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
|
||||
{
|
||||
xcb_randr_get_monitors_cookie_t monitorsCookie = data->ffxcb_randr_get_monitors(data->connection, screen->root, true);
|
||||
xcb_randr_get_monitors_reply_t* monitorsReply = data->ffxcb_randr_get_monitors_reply(data->connection, monitorsCookie, NULL);
|
||||
FF_AUTO_FREE xcb_randr_get_monitors_reply_t* monitorsReply = data->ffxcb_randr_get_monitors_reply(data->connection, monitorsCookie, NULL);
|
||||
if(monitorsReply == NULL)
|
||||
return false;
|
||||
|
||||
@ -360,8 +352,6 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
|
||||
data->ffxcb_randr_monitor_info_next(&monitorInfoIterator);
|
||||
}
|
||||
|
||||
free(monitorsReply);
|
||||
|
||||
return foundMonitor;
|
||||
}
|
||||
|
||||
@ -392,7 +382,9 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
0,
|
||||
(uint32_t) screen->width_in_millimeters,
|
||||
(uint32_t) screen->height_in_millimeters
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,9 @@ void ffdsConnectXlib(FFDisplayServerResult* result)
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
0,
|
||||
(uint32_t) WidthMMOfScreen(screen),
|
||||
(uint32_t) HeightMMOfScreen(screen)
|
||||
);
|
||||
}
|
||||
|
||||
@ -117,7 +119,6 @@ typedef struct XrandrData
|
||||
FF_LIBRARY_SYMBOL(XInternAtom)
|
||||
FF_LIBRARY_SYMBOL(XGetAtomName);
|
||||
FF_LIBRARY_SYMBOL(XFree);
|
||||
FF_LIBRARY_SYMBOL(XRRConfigCurrentRate)
|
||||
FF_LIBRARY_SYMBOL(XRRGetMonitors)
|
||||
FF_LIBRARY_SYMBOL(XRRGetScreenResourcesCurrent)
|
||||
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
|
||||
@ -149,7 +150,7 @@ static double xrandrHandleMode(XrandrData* data, RRMode mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary)
|
||||
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary, XRROutputInfo* output, FFDisplayType displayType)
|
||||
{
|
||||
//We do the check here, because we want the best fallback display if this call failed
|
||||
if(data->screenResources == NULL)
|
||||
@ -185,16 +186,18 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool
|
||||
(uint32_t) crtcInfo->height,
|
||||
rotation,
|
||||
name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
displayType,
|
||||
primary,
|
||||
0
|
||||
0,
|
||||
(uint32_t) output->mm_width,
|
||||
(uint32_t) output->mm_height
|
||||
);
|
||||
|
||||
data->ffXRRFreeCrtcInfo(crtcInfo);
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary)
|
||||
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType)
|
||||
{
|
||||
XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, data->screenResources, output);
|
||||
if(outputInfo == NULL)
|
||||
@ -218,7 +221,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
|
||||
if (edidData)
|
||||
data->ffXFree(edidData);
|
||||
}
|
||||
bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary);
|
||||
bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary, outputInfo, displayType);
|
||||
|
||||
data->ffXRRFreeOutputInfo(outputInfo);
|
||||
|
||||
@ -231,13 +234,14 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
|
||||
char* xname = data->ffXGetAtomName(data->display, monitorInfo->name);
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(xname);
|
||||
data->ffXFree(xname);
|
||||
FFDisplayType displayType = ffdsGetDisplayType(name.chars);
|
||||
for(int i = 0; i < monitorInfo->noutput; i++)
|
||||
{
|
||||
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary))
|
||||
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary, displayType))
|
||||
foundOutput = true;
|
||||
}
|
||||
|
||||
return foundOutput ? true : ffdsAppendDisplay(
|
||||
return foundOutput ? true : !!ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) monitorInfo->width,
|
||||
(uint32_t) monitorInfo->height,
|
||||
@ -246,9 +250,11 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
|
||||
(uint32_t) monitorInfo->height,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
displayType,
|
||||
!!monitorInfo->primary,
|
||||
0
|
||||
0,
|
||||
(uint32_t) monitorInfo->mwidth,
|
||||
(uint32_t) monitorInfo->mheight
|
||||
);
|
||||
}
|
||||
|
||||
@ -296,7 +302,9 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
0,
|
||||
(uint32_t) WidthMMOfScreen(screen),
|
||||
(uint32_t) HeightMMOfScreen(screen)
|
||||
);
|
||||
}
|
||||
|
||||
@ -312,7 +320,6 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentRate,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResourcesCurrent,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,);
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
#define FF_GPU_VMEM_SIZE_UNSET ((uint64_t)-1)
|
||||
#define FF_GPU_FREQUENCY_UNSET (0/0.0)
|
||||
#define FF_GPU_FREQUENCY_UNSET 0
|
||||
|
||||
extern const char* FF_GPU_VENDOR_NAME_APPLE;
|
||||
extern const char* FF_GPU_VENDOR_NAME_AMD;
|
||||
@ -32,7 +32,7 @@ typedef struct FFGPUResult
|
||||
FFstrbuf platformApi;
|
||||
double temperature;
|
||||
int32_t coreCount;
|
||||
double frequency; // Maximum time clock frequency in GHz
|
||||
uint32_t frequency; // Maximum time clock frequency in MHz
|
||||
FFGPUMemory dedicated;
|
||||
FFGPUMemory shared;
|
||||
uint64_t deviceId; // Used internally, may be uninitialized
|
||||
|
@ -60,7 +60,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
}
|
||||
|
||||
if (result.frequency)
|
||||
*result.frequency = device->coreClock / 1000.; // Maximum frequency
|
||||
*result.frequency = (uint32_t) device->coreClock; // Maximum frequency
|
||||
|
||||
if (result.type)
|
||||
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
|
@ -36,6 +36,43 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
#include "util/apple/cf_helpers.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
static const char* detectFrequency(FFGPUResult* gpu)
|
||||
{
|
||||
// https://github.com/giampaolo/psutil/pull/2222/files
|
||||
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceNameMatching("pmgr"));
|
||||
if (!entryDevice)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
if (!IOObjectConformsTo(entryDevice, "AppleARMIODevice"))
|
||||
return "\"pmgr\" should conform to \"AppleARMIODevice\"";
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFDataRef freqProperty = (CFDataRef) IORegistryEntryCreateCFProperty(entryDevice, CFSTR("voltage-states9-sram"), kCFAllocatorDefault, kNilOptions);
|
||||
if (CFGetTypeID(freqProperty) != CFDataGetTypeID())
|
||||
return "\"voltage-states9-sram\" in \"pmgr\" is not found";
|
||||
|
||||
// voltage-states5-sram stores supported <frequency / voltage> pairs of gpu from the lowest to the highest
|
||||
CFIndex propLength = CFDataGetLength(freqProperty);
|
||||
if (propLength == 0 || propLength % (CFIndex) sizeof(uint32_t) * 2 != 0)
|
||||
return "Invalid \"voltage-states9-sram\" length";
|
||||
|
||||
uint32_t* pStart = (uint32_t*) CFDataGetBytePtr(freqProperty);
|
||||
uint32_t pMax = *pStart;
|
||||
for (CFIndex i = 2; i < propLength / (CFIndex) sizeof(uint32_t) && pStart[i] > 0; i += 2 /* skip voltage */)
|
||||
pMax = pMax > pStart[i] ? pMax : pStart[i];
|
||||
|
||||
if (pMax > 0)
|
||||
gpu->frequency = pMax / 1000 / 1000;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
|
||||
@ -94,6 +131,11 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
||||
else if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA || vendorStr == FF_GPU_VENDOR_NAME_AMD)
|
||||
gpu->type = FF_GPU_TYPE_DISCRETE;
|
||||
|
||||
#ifdef __aarch64__
|
||||
if (vendorStr == FF_GPU_VENDOR_NAME_APPLE)
|
||||
detectFrequency(gpu);
|
||||
#endif
|
||||
}
|
||||
|
||||
gpu->temperature = options->temp ? detectGpuTemp(&gpu->name) : FF_GPU_TEMP_UNSET;
|
||||
|
@ -41,7 +41,7 @@ typedef struct FFGpuDriverResult
|
||||
FFGPUMemory* memory;
|
||||
uint32_t* coreCount;
|
||||
FFGPUType* type;
|
||||
double* frequency;
|
||||
uint32_t* frequency;
|
||||
} FFGpuDriverResult;
|
||||
|
||||
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
|
||||
|
@ -191,7 +191,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
maxValue = props.max;
|
||||
}
|
||||
}
|
||||
*result.frequency = maxValue / 1000;
|
||||
*result.frequency = (uint32_t) (maxValue + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,19 +133,26 @@ static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf*
|
||||
ffStrbufSubstrAfter(&gpu->name, (uint32_t) strlen("Intel "));
|
||||
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
|
||||
ffStrbufAppendS(pciDir, "/drm/");
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
|
||||
if (!dirp) return;
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
if (ffStrbufEqualS(&gpu->driver, "xe"))
|
||||
{
|
||||
if (ffStrStartsWith(entry->d_name, "card")) break;
|
||||
ffStrbufAppendS(pciDir, "/tile0/gt0/freq0/max_freq");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(pciDir, "/drm/");
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
|
||||
if (!dirp) return;
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (ffStrStartsWith(entry->d_name, "card")) break;
|
||||
}
|
||||
if (!entry) return;
|
||||
ffStrbufAppendS(pciDir, entry->d_name);
|
||||
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
|
||||
}
|
||||
if (!entry) return;
|
||||
ffStrbufAppendS(pciDir, entry->d_name);
|
||||
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
|
||||
if (ffReadFileBuffer(pciDir->chars, buffer))
|
||||
gpu->frequency = ffStrbufToDouble(buffer) / 1000.0;
|
||||
gpu->frequency = (uint32_t) ffStrbufToUInt(buffer, 0);
|
||||
}
|
||||
|
||||
static bool loadPciIds(FFstrbuf* pciids)
|
||||
@ -339,7 +346,7 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
|
||||
}) >= 0)
|
||||
{
|
||||
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
|
||||
gpu->frequency = paramsGlobal.max_frequency_khz / 1e6;
|
||||
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
|
||||
gpu->deviceId = paramsGlobal.chip_id;
|
||||
}
|
||||
}
|
||||
|
@ -122,11 +122,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
nvmlData.ffnvmlDeviceGetNumGpuCores(device, result.coreCount);
|
||||
|
||||
if (result.frequency)
|
||||
{
|
||||
uint32_t clockMHz;
|
||||
if (nvmlData.ffnvmlDeviceGetMaxClockInfo(device, NVML_CLOCK_GRAPHICS, &clockMHz) == NVML_SUCCESS)
|
||||
*result.frequency = clockMHz / 1000.;
|
||||
}
|
||||
nvmlData.ffnvmlDeviceGetMaxClockInfo(device, NVML_CLOCK_GRAPHICS, result.frequency);
|
||||
|
||||
return NULL;
|
||||
|
||||
|
@ -22,10 +22,10 @@ static const char* getProductNameWithHwModel(const FFstrbuf* hwModel)
|
||||
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,4")) return "MacBook Pro (16-inch, 2019)";
|
||||
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,1")) return "MacBook Pro (16-inch, 2019)";
|
||||
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)";
|
||||
|
@ -1,10 +1,22 @@
|
||||
#include "initsystem.h"
|
||||
#include "common/processing.h"
|
||||
#include <unistd.h>
|
||||
|
||||
const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
{
|
||||
const char* error = ffProcessGetBasicInfoLinux((int) result->pid, &result->name, NULL, NULL);
|
||||
if (error) return error;
|
||||
if (error)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
if (access("/system/bin/init", F_OK) == 0)
|
||||
{
|
||||
ffStrbufSetStatic(&result->exe, "/system/bin/init");
|
||||
ffStrbufSetStatic(&result->name, "init");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
const char* _;
|
||||
// In linux /proc/1/exe is not readable
|
||||
|
@ -5,6 +5,7 @@ typedef struct FFMonitorResult
|
||||
FFstrbuf name;
|
||||
uint32_t width; // native / maximum resolution, in pixels
|
||||
uint32_t height; // native / maximum resolution, in pixels
|
||||
double refreshRate;// maximum refresh rate in native resolution, in Hz
|
||||
uint32_t physicalWidth; // in mm
|
||||
uint32_t physicalHeight; // in mm
|
||||
bool hdrCompatible;
|
||||
|
@ -19,7 +19,7 @@ static bool detectHdrSupportWithNSScreen(FFDisplayResult* display)
|
||||
NSScreen* mainScreen = NSScreen.mainScreen;
|
||||
if (display->primary)
|
||||
{
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
return mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
|
||||
#else
|
||||
return mainScreen.maximumExtendedDynamicRangeColorComponentValue > 1;
|
||||
@ -100,10 +100,22 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
monitor->physicalHeight = (uint32_t) (size.height + 0.5);
|
||||
monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) ||
|
||||
detectHdrSupportWithNSScreen(display);
|
||||
monitor->serial = CGDisplaySerialNumber((CGDirectDisplayID) display->id);
|
||||
|
||||
int64_t serial, year, week;
|
||||
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplaySerialNumber"), &serial) == NULL)
|
||||
monitor->serial = (uint32_t) (uint64_t) serial;
|
||||
FF_CFTYPE_AUTO_RELEASE CFArrayRef modes = CGDisplayCopyAllDisplayModes((CGDirectDisplayID) display->id, NULL);
|
||||
double maxRefreshRate = 0;
|
||||
for (uint32_t j = 0; j < CFArrayGetCount(modes); ++j)
|
||||
{
|
||||
CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, j);
|
||||
if (CGDisplayModeGetWidth(mode) == (uint32_t) width && CGDisplayModeGetHeight(mode) == (uint32_t) height)
|
||||
{
|
||||
double refreshRate = CGDisplayModeGetRefreshRate(mode);
|
||||
if (refreshRate > maxRefreshRate) maxRefreshRate = refreshRate;
|
||||
}
|
||||
}
|
||||
monitor->refreshRate = maxRefreshRate;
|
||||
|
||||
int64_t year, week;
|
||||
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayYearManufacture"), &year) == NULL)
|
||||
monitor->manufactureYear = (uint16_t) year;
|
||||
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayWeekManufacture"), &week) == NULL)
|
||||
|
@ -1,13 +1,178 @@
|
||||
#include "monitor.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "common/library.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef FF_HAVE_XRANDR
|
||||
|
||||
const char* ffDetectMonitor(FFlist* results)
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
typedef struct XrandrData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(XInternAtom)
|
||||
FF_LIBRARY_SYMBOL(XGetAtomName);
|
||||
FF_LIBRARY_SYMBOL(XFree);
|
||||
FF_LIBRARY_SYMBOL(XRRGetMonitors)
|
||||
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
|
||||
FF_LIBRARY_SYMBOL(XRRGetOutputProperty)
|
||||
FF_LIBRARY_SYMBOL(XRRFreeOutputInfo)
|
||||
FF_LIBRARY_SYMBOL(XRRFreeMonitors)
|
||||
|
||||
//Init once
|
||||
Display* display;
|
||||
|
||||
//Init per screen
|
||||
XRRScreenResources* screenResources;
|
||||
} XrandrData;
|
||||
|
||||
static const char* xrandrHandleMonitors(XrandrData* data, Screen* screen, FFlist* results)
|
||||
{
|
||||
int numberOfMonitors;
|
||||
XRRMonitorInfo* monitorInfos = data->ffXRRGetMonitors(data->display, RootWindowOfScreen(screen), True, &numberOfMonitors);
|
||||
if(monitorInfos == NULL)
|
||||
return "XRRGetMonitors() failed";
|
||||
|
||||
for(int i = 0; i < numberOfMonitors; i++)
|
||||
{
|
||||
XRRMonitorInfo* monitorInfo = &monitorInfos[i];
|
||||
for(int i = 0; i < monitorInfo->noutput; i++)
|
||||
{
|
||||
RROutput output = monitorInfo->outputs[i];
|
||||
XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, data->screenResources, output);
|
||||
if(outputInfo == NULL)
|
||||
continue;
|
||||
|
||||
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
|
||||
ffStrbufInit(&display->name);
|
||||
display->width = 0;
|
||||
display->height = 0;
|
||||
display->manufactureYear = 0;
|
||||
display->manufactureWeek = 0;
|
||||
display->serial = 0;
|
||||
display->hdrCompatible = false;
|
||||
display->refreshRate = 0;
|
||||
|
||||
bool edidOk = false;
|
||||
Atom atomEdid = data->ffXInternAtom(data->display, "EDID", true);
|
||||
if (atomEdid != None)
|
||||
{
|
||||
int actual_format = 0;
|
||||
unsigned long nitems = 0, bytes_after = 0;
|
||||
Atom actual_type = None;
|
||||
uint8_t* edidData = NULL;
|
||||
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &edidData) == Success)
|
||||
{
|
||||
if (nitems > 0 && nitems % 128 == 0)
|
||||
{
|
||||
ffEdidGetName(edidData, &display->name);
|
||||
ffEdidGetPhysicalResolution(edidData, &display->width, &display->height);
|
||||
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
|
||||
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) nitems);
|
||||
edidOk = true;
|
||||
}
|
||||
}
|
||||
if (edidData)
|
||||
data->ffXFree(edidData);
|
||||
}
|
||||
|
||||
if (!edidOk)
|
||||
{
|
||||
ffStrbufSetS(&display->name, data->ffXGetAtomName(data->display, monitorInfo->name));
|
||||
display->physicalWidth = (uint32_t) monitorInfo->mwidth;
|
||||
display->physicalHeight = (uint32_t) monitorInfo->mheight;
|
||||
display->width = (uint32_t) monitorInfo->width;
|
||||
display->height = (uint32_t) monitorInfo->height;
|
||||
}
|
||||
|
||||
for(int i = 0; i < data->screenResources->nmode; i++)
|
||||
{
|
||||
bool found = false;
|
||||
for (int j = 0; j < outputInfo->nmode; ++j)
|
||||
{
|
||||
if (data->screenResources->modes[i].id == outputInfo->modes[j])
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
XRRModeInfo* modeInfo = &data->screenResources->modes[i];
|
||||
double refreshRate = (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
|
||||
if (edidOk)
|
||||
{
|
||||
if (display->width != modeInfo->width || display->height != modeInfo->height)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (display->width < modeInfo->width || display->height < modeInfo->height)
|
||||
{
|
||||
display->width = (uint32_t) modeInfo->width;
|
||||
display->height = (uint32_t) modeInfo->height;
|
||||
display->refreshRate = refreshRate;
|
||||
continue;
|
||||
}
|
||||
else if (display->width != modeInfo->width || display->height != modeInfo->height)
|
||||
continue;
|
||||
}
|
||||
if (display->refreshRate < refreshRate)
|
||||
display->refreshRate = refreshRate;
|
||||
}
|
||||
}
|
||||
data->ffXRRFreeOutputInfo(outputInfo);
|
||||
}
|
||||
}
|
||||
|
||||
data->ffXRRFreeMonitors(monitorInfos);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectByXrandr(FFlist* results)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xrandr, &instance.config.library.libXrandr, "dlopen libXrandr" FF_LIBRARY_EXTENSION " failed", "libXrandr" FF_LIBRARY_EXTENSION, 3)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XOpenDisplay)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XCloseDisplay)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XRRGetScreenResourcesCurrent);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XRRFreeScreenResources);
|
||||
|
||||
XrandrData data;
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XInternAtom);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XGetAtomName);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XFree);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetMonitors);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetOutputInfo);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetOutputProperty);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeOutputInfo);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeMonitors);
|
||||
|
||||
data.display = ffXOpenDisplay(NULL);
|
||||
if(data.display == NULL)
|
||||
return "XOpenDisplay() failed";
|
||||
|
||||
for(int i = 0; i < ScreenCount(data.display); i++)
|
||||
{
|
||||
Screen* screen = ScreenOfDisplay(data.display, i);
|
||||
data.screenResources = ffXRRGetScreenResourcesCurrent(data.display, RootWindowOfScreen(screen));
|
||||
xrandrHandleMonitors(&data, screen, results);
|
||||
ffXRRFreeScreenResources(data.screenResources);
|
||||
}
|
||||
|
||||
ffXCloseDisplay(data.display);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif // FF_HAVE_XRANDR
|
||||
|
||||
#ifdef __linux__
|
||||
FF_MAYBE_UNUSED static const char* detectByDrm(FFlist* results)
|
||||
{
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
@ -61,6 +226,7 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
|
||||
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
|
||||
display->refreshRate = 0;
|
||||
}
|
||||
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
@ -69,3 +235,20 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
closedir(dirp);
|
||||
return NULL;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
const char* ffDetectMonitor(FFlist* results)
|
||||
{
|
||||
const char* error = "Fastfetch was compiled without xrandr support";
|
||||
|
||||
#ifdef FF_HAVE_XRANDR
|
||||
error = detectByXrandr(results);
|
||||
if (!error) return NULL;
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
error = detectByDrm(results);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -1,54 +1,116 @@
|
||||
#include "monitor.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <devguid.h>
|
||||
|
||||
static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
{
|
||||
if(*hdev)
|
||||
SetupDiDestroyDeviceInfoList(*hdev);
|
||||
}
|
||||
|
||||
const char* ffDetectMonitor(FFlist* results)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
||||
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
|
||||
SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, 0, 0, DIGCF_PRESENT);
|
||||
if(hdev == INVALID_HANDLE_VALUE)
|
||||
return "SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR) failed";
|
||||
DISPLAYCONFIG_PATH_INFO paths[128];
|
||||
uint32_t pathCount = sizeof(paths) / sizeof(paths[0]);
|
||||
DISPLAYCONFIG_MODE_INFO modes[256];
|
||||
uint32_t modeCount = sizeof(modes) / sizeof(modes[0]);
|
||||
|
||||
SP_DEVINFO_DATA did = { .cbSize = sizeof(did) };
|
||||
for (DWORD idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); ++idev)
|
||||
if (QueryDisplayConfig(
|
||||
QDC_ONLY_ACTIVE_PATHS,
|
||||
&pathCount,
|
||||
paths,
|
||||
&modeCount,
|
||||
modes,
|
||||
NULL) != ERROR_SUCCESS)
|
||||
return "QueryDisplayConfig() failed";
|
||||
|
||||
if (pathCount == 0)
|
||||
return "QueryDisplayConfig() returns 0 paths";
|
||||
|
||||
for (uint32_t i = 0; i < pathCount; ++i)
|
||||
{
|
||||
FF_HKEY_AUTO_DESTROY hKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
|
||||
if (!hKey) continue;
|
||||
DISPLAYCONFIG_PATH_INFO* path = &paths[i];
|
||||
|
||||
FF_AUTO_FREE uint8_t* edidData = NULL;
|
||||
uint32_t edidLength = 0;
|
||||
if (!ffRegReadData(hKey, L"EDID", &edidData, &edidLength, NULL)) continue;
|
||||
if (edidLength == 0 || edidLength % 128 != 0)
|
||||
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {
|
||||
.header = {
|
||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME,
|
||||
.size = sizeof(targetName),
|
||||
.adapterId = path->targetInfo.adapterId,
|
||||
.id = path->targetInfo.id,
|
||||
},
|
||||
};
|
||||
if (DisplayConfigGetDeviceInfo(&targetName.header) != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
uint32_t width, height;
|
||||
ffEdidGetPhysicalResolution(edidData, &width, &height);
|
||||
if (width == 0 || height == 0) continue;
|
||||
wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
|
||||
wchar_t* pRegPath = regPath + strlen("SYSTEM\\CurrentControlSet\\Enum");
|
||||
wchar_t* pDevPath = targetName.monitorDevicePath + strlen("\\\\?");
|
||||
while (*pDevPath && *pDevPath != L'{')
|
||||
{
|
||||
if (*pDevPath == L'#')
|
||||
*pRegPath = L'\\';
|
||||
else
|
||||
*pRegPath = *pDevPath;
|
||||
++pRegPath;
|
||||
++pDevPath;
|
||||
assert(pRegPath < regPath + sizeof(regPath) / sizeof(wchar_t) + strlen("Device Parameters"));
|
||||
}
|
||||
wcscpy(pRegPath, L"Device Parameters");
|
||||
|
||||
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
|
||||
display->width = width;
|
||||
display->height = height;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
|
||||
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength); // Doesn't work. edidLength is always 128
|
||||
ffStrbufInit(&display->name);
|
||||
ffEdidGetName(edidData, &display->name);
|
||||
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
|
||||
uint8_t edidData[1024];
|
||||
DWORD edidLength = sizeof(edidData);
|
||||
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, regPath, L"EDID", RRF_RT_REG_BINARY, NULL, edidData, &edidLength) == ERROR_SUCCESS &&
|
||||
edidLength > 0 && edidLength % 128 == 0)
|
||||
{
|
||||
uint32_t width, height;
|
||||
ffEdidGetPhysicalResolution(edidData, &width, &height);
|
||||
if (width == 0 || height == 0) continue;
|
||||
|
||||
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
|
||||
display->width = width;
|
||||
display->height = height;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
|
||||
ffStrbufInit(&display->name);
|
||||
ffEdidGetName(edidData, &display->name);
|
||||
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
|
||||
display->refreshRate = 0;
|
||||
display->hdrCompatible = false;
|
||||
|
||||
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
|
||||
.header = {
|
||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
|
||||
.size = sizeof(advColorInfo),
|
||||
.adapterId = path->targetInfo.adapterId,
|
||||
.id = path->targetInfo.id,
|
||||
}
|
||||
};
|
||||
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
|
||||
display->hdrCompatible = !!advColorInfo.advancedColorSupported;
|
||||
else
|
||||
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
|
||||
|
||||
DISPLAYCONFIG_TARGET_PREFERRED_MODE preferredMode = {
|
||||
.header = {
|
||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE,
|
||||
.size = sizeof(preferredMode),
|
||||
.adapterId = path->targetInfo.adapterId,
|
||||
.id = path->targetInfo.id,
|
||||
}
|
||||
};
|
||||
if (DisplayConfigGetDeviceInfo(&preferredMode.header) == ERROR_SUCCESS)
|
||||
{
|
||||
if (preferredMode.width == width && preferredMode.height == height)
|
||||
{
|
||||
DISPLAYCONFIG_RATIONAL freq = preferredMode.targetMode.targetVideoSignalInfo.vSyncFreq;
|
||||
display->refreshRate = freq.Numerator / (double) freq.Denominator;
|
||||
}
|
||||
}
|
||||
|
||||
DISPLAYCONFIG_VIDEO_SIGNAL_INFO current = modes[path->targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo;
|
||||
if (current.activeSize.cx == width && current.activeSize.cy == height)
|
||||
{
|
||||
double refreshRate = current.vSyncFreq.Numerator / (double) current.vSyncFreq.Denominator;
|
||||
if (refreshRate > display->refreshRate) display->refreshRate = refreshRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
|
||||
{
|
||||
cl_uint value;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(value), &value, NULL) == CL_SUCCESS)
|
||||
gpu->frequency = value / 1000.;
|
||||
gpu->frequency = value;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -262,10 +262,10 @@ static void detectFromWindowsTerminal(const FFstrbuf* terminalExe, FFTerminalFon
|
||||
static bool queryKittyTerm(const char* query, FFstrbuf* res)
|
||||
{
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
|
||||
char buffer[64] = "";
|
||||
char buffer[256] = "";
|
||||
if (ffGetTerminalResponse(
|
||||
query, // kitty-query-font_family;kitty-query-font_size
|
||||
"\eP1+r%*[^=]=%64[^\e]\e\\", buffer) == NULL && *buffer)
|
||||
"\eP1+r%*[^=]=%255[^\e]\e\\", buffer) == NULL)
|
||||
{
|
||||
// decode hex string
|
||||
for (const char* p = buffer; p[0] && p[1]; p += 2)
|
||||
@ -350,12 +350,19 @@ static void detectTerminator(FFTerminalFontResult* result)
|
||||
ffFontInitPango(&result->font, fontName.chars);
|
||||
}
|
||||
|
||||
static bool detectWezterm(FFTerminalFontResult* result)
|
||||
static bool detectWezterm(const FFstrbuf* exe, FFTerminalFontResult* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cli = ffStrbufCreateCopy(exe);
|
||||
ffStrbufSubstrBeforeLastC(&cli, '-');
|
||||
|
||||
#ifdef _WIN32
|
||||
ffStrbufAppendS(&cli, ".exe");
|
||||
#endif
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
|
||||
|
||||
ffStrbufSetS(&result->error, ffProcessAppendStdOut(&fontName, (char* const[]){
|
||||
"wezterm",
|
||||
cli.chars,
|
||||
"ls-fonts",
|
||||
"--text",
|
||||
"a",
|
||||
@ -438,7 +445,7 @@ static bool detectTerminalFontCommon(const FFTerminalResult* terminal, FFTermina
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "terminator"))
|
||||
detectTerminator(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "wezterm-gui"))
|
||||
detectWezterm(terminalFont);
|
||||
detectWezterm(&terminal->exe, terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "tabby"))
|
||||
detectTabby(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "contour"))
|
||||
|
@ -352,11 +352,15 @@ FF_MAYBE_UNUSED static bool getTerminalVersionCockpit(FFstrbuf* exe, FFstrbuf* v
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionXterm(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
if(ffProcessAppendStdOut(version, (char* const[]){
|
||||
exe->chars,
|
||||
"-v",
|
||||
NULL
|
||||
})) return false;
|
||||
ffStrbufSetS(version, getenv("XTERM_VERSION"));
|
||||
if (!version->length)
|
||||
{
|
||||
if(ffProcessAppendStdOut(version, (char* const[]){
|
||||
exe->chars,
|
||||
"-v",
|
||||
NULL
|
||||
})) return false;
|
||||
}
|
||||
|
||||
//xterm(273)
|
||||
ffStrbufTrimRight(version, ')');
|
||||
@ -477,14 +481,37 @@ static bool getTerminalVersionZellij(FFstrbuf* exe, FFstrbuf* version)
|
||||
return version->length > 0;
|
||||
}
|
||||
|
||||
static bool getTerminalVersionZed(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cli = ffStrbufCreateCopy(exe);
|
||||
ffStrbufSubstrBeforeLastC(&cli, '/');
|
||||
ffStrbufAppendS(&cli, "/cli"
|
||||
#ifdef _WIN32
|
||||
".exe"
|
||||
#endif
|
||||
);
|
||||
|
||||
if(ffProcessAppendStdOut(version, (char* const[]) {
|
||||
cli.chars,
|
||||
"--version",
|
||||
NULL
|
||||
}) != NULL)
|
||||
return false;
|
||||
|
||||
// Zed 0.142.6 – /Applications/Zed.app
|
||||
ffStrbufSubstrAfterFirstC(version, ' ');
|
||||
ffStrbufSubstrBeforeFirstC(version, ' ');
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static bool getTerminalVersionKitty(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
char versionHex[64] = "";
|
||||
char versionHex[64];
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
|
||||
if (ffGetTerminalResponse(
|
||||
"\eP+q6b697474792d71756572792d76657273696f6e\e\\", // kitty-query-version
|
||||
"\eP1+r%*[^=]=%64[^\e]\e\\\\", versionHex) == NULL && *versionHex)
|
||||
"\eP1+r%*[^=]=%63[^\e]\e\\\\", versionHex) == NULL)
|
||||
{
|
||||
// decode hex string
|
||||
for (const char* p = versionHex; p[0] && p[1]; p += 2)
|
||||
@ -646,6 +673,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
||||
if(ffStrbufStartsWithIgnCaseS(processName, "zellij"))
|
||||
return getTerminalVersionZellij(exe, version);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(processName, "zed"))
|
||||
return getTerminalVersionZed(exe, version);
|
||||
|
||||
const char* termProgramVersion = getenv("TERM_PROGRAM_VERSION");
|
||||
if(termProgramVersion)
|
||||
{
|
||||
|
22
src/logo/ascii/altlinux.txt
Normal file
22
src/logo/ascii/altlinux.txt
Normal file
@ -0,0 +1,22 @@
|
||||
##############
|
||||
######################
|
||||
##########################
|
||||
##+$2###$1#######################
|
||||
#####$2#$1*$2###%+$1######################
|
||||
########$2%$1*#$2%#####$1###################
|
||||
##########$2##$1*#*$2#######%+$1##############
|
||||
#############$2%#############%$1############
|
||||
#############$2+################$1##########
|
||||
##############$2################*$1#########
|
||||
##############$2+################+$1########
|
||||
###############$2##########$1###$2+##%$1########
|
||||
###############$2+########$1######$2###$1#######
|
||||
#############$2*####$1############$2%#+$1#######
|
||||
############$2+###$3####$1##########$2%#*$1#######
|
||||
##########$2###*$3######$2+#+$1#####$2+##*$1######
|
||||
#########$2##%$3#####$2:%#####$1###$2###*$1#####
|
||||
########$2%#+$3######$2#############$1####
|
||||
#####$2##%:$3######$2:############$1##
|
||||
##$2+##*$3########$2############$1
|
||||
$2###$3#########$2##########$1
|
||||
$3########$2######
|
7
src/logo/ascii/void2_small.txt
Normal file
7
src/logo/ascii/void2_small.txt
Normal file
@ -0,0 +1,7 @@
|
||||
_______
|
||||
_ \______ -
|
||||
| \ ___ \ |
|
||||
| | / \ | |
|
||||
| | \___/ | |
|
||||
| \______ \_|
|
||||
-_______\
|
@ -1,7 +1,7 @@
|
||||
_______
|
||||
_ \______ -
|
||||
| \ ___ \ |
|
||||
| | / \ | |
|
||||
| | \___/ | |
|
||||
| \______ \_|
|
||||
-_______\
|
||||
____
|
||||
'pfPfp.%
|
||||
// _._ \\
|
||||
UU |===| UU
|
||||
\\ ^~^ //
|
||||
`0PpppP'
|
||||
`````
|
||||
|
@ -112,6 +112,18 @@ static const FFlogo A[] = {
|
||||
.colorKeys = FF_COLOR_FG_CYAN,
|
||||
.colorTitle = FF_COLOR_FG_CYAN,
|
||||
},
|
||||
// ALTLinux
|
||||
{
|
||||
.names = {"ALTLinux", "Sisyphus"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ALTLINUX,
|
||||
.colors = {
|
||||
FF_COLOR_FG_YELLOW,
|
||||
FF_COLOR_FG_BLACK,
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
.colorKeys = FF_COLOR_FG_YELLOW,
|
||||
.colorTitle = FF_COLOR_FG_YELLOW,
|
||||
},
|
||||
// Amazon
|
||||
{
|
||||
.names = {"Amazon"},
|
||||
@ -4480,6 +4492,17 @@ static const FFlogo V[] = {
|
||||
.colorKeys = FF_COLOR_FG_WHITE,
|
||||
.colorTitle = FF_COLOR_FG_GREEN,
|
||||
},
|
||||
// Void2Small
|
||||
{
|
||||
.names = {"void2_small", "void-linux2-small"},
|
||||
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_VOID2_SMALL,
|
||||
.colors = {
|
||||
FF_COLOR_FG_GREEN,
|
||||
},
|
||||
.colorKeys = FF_COLOR_FG_WHITE,
|
||||
.colorTitle = FF_COLOR_FG_GREEN,
|
||||
},
|
||||
// LAST
|
||||
{},
|
||||
};
|
||||
|
@ -20,15 +20,23 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(128);
|
||||
|
||||
if (options->symbol == FF_COLORS_SYMBOL_BLOCK)
|
||||
if (options->symbol == FF_COLORS_SYMBOL_BLOCK || options->symbol == FF_COLORS_SYMBOL_BACKGROUND)
|
||||
{
|
||||
// 3%d: Set the foreground color
|
||||
for(uint8_t i = options->block.range[0]; i <= min(options->block.range[1], 7); i++)
|
||||
{
|
||||
if (!instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[3%dm", i);
|
||||
for (uint8_t j = 0; j < options->block.width; j++)
|
||||
ffStrbufAppendS(&result, "█");
|
||||
if (options->symbol == FF_COLORS_SYMBOL_BLOCK)
|
||||
{
|
||||
if (!instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[3%dm", i);
|
||||
for (uint8_t j = 0; j < options->block.width; j++)
|
||||
ffStrbufAppendS(&result, "█");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[4%dm", i);
|
||||
ffStrbufAppendNC(&result, options->block.width, ' ');
|
||||
}
|
||||
}
|
||||
if (result.length > 0)
|
||||
{
|
||||
@ -38,20 +46,27 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
if (options->paddingLeft > 0)
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
|
||||
if (!instance.config.display.pipe)
|
||||
if (!instance.config.display.pipe || options->symbol == FF_COLORS_SYMBOL_BACKGROUND)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
ffStrbufPutTo(&result, stdout);
|
||||
ffStrbufClear(&result);
|
||||
}
|
||||
|
||||
// 1: Set everything to bolt. This causes normal colors on some systems to be bright.
|
||||
// 9%d: Set the foreground to the bright color
|
||||
for(uint8_t i = max(options->block.range[0], 8); i <= options->block.range[1]; i++)
|
||||
{
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[9%dm", i - 8);
|
||||
for (uint8_t j = 0; j < options->block.width; j++)
|
||||
ffStrbufAppendS(&result, "█");
|
||||
if (options->symbol == FF_COLORS_SYMBOL_BLOCK)
|
||||
{
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[9%dm", i - 8);
|
||||
for (uint8_t j = 0; j < options->block.width; j++)
|
||||
ffStrbufAppendS(&result, "█");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[10%dm", i - 8);
|
||||
ffStrbufAppendNC(&result, options->block.width, ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -87,7 +102,7 @@ void ffPrintColors(FFColorsOptions* options)
|
||||
|
||||
if(options->paddingLeft > 0)
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
if(!instance.config.display.pipe)
|
||||
if(!instance.config.display.pipe || options->symbol == FF_COLORS_SYMBOL_BACKGROUND)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
ffStrbufPutTo(&result, stdout);
|
||||
}
|
||||
@ -109,6 +124,7 @@ bool ffParseColorsCommandOptions(FFColorsOptions* options, const char* key, cons
|
||||
{
|
||||
options->symbol = (FFColorsSymbol) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "block", FF_COLORS_SYMBOL_BLOCK },
|
||||
{ "background", FF_COLORS_SYMBOL_BACKGROUND },
|
||||
{ "circle", FF_COLORS_SYMBOL_CIRCLE },
|
||||
{ "diamond", FF_COLORS_SYMBOL_DIAMOND },
|
||||
{ "triangle", FF_COLORS_SYMBOL_TRIANGLE },
|
||||
@ -164,6 +180,7 @@ void ffParseColorsJsonObject(FFColorsOptions* options, yyjson_val* module)
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "block", FF_COLORS_SYMBOL_BLOCK },
|
||||
{ "background", FF_COLORS_SYMBOL_BACKGROUND },
|
||||
{ "circle", FF_COLORS_SYMBOL_CIRCLE },
|
||||
{ "diamond", FF_COLORS_SYMBOL_DIAMOND },
|
||||
{ "triangle", FF_COLORS_SYMBOL_TRIANGLE },
|
||||
@ -278,7 +295,7 @@ void ffInitColorsOptions(FFColorsOptions* options)
|
||||
);
|
||||
ffOptionInitModuleArg(&options->moduleArgs);
|
||||
ffStrbufSetStatic(&options->moduleArgs.key, " ");
|
||||
options->symbol = FF_COLORS_SYMBOL_BLOCK;
|
||||
options->symbol = FF_COLORS_SYMBOL_BACKGROUND;
|
||||
options->paddingLeft = 0;
|
||||
options->block = (FFBlockConfig) {
|
||||
.width = 3,
|
||||
|
@ -7,6 +7,7 @@
|
||||
typedef enum FFColorsSymbol
|
||||
{
|
||||
FF_COLORS_SYMBOL_BLOCK,
|
||||
FF_COLORS_SYMBOL_BACKGROUND,
|
||||
FF_COLORS_SYMBOL_CIRCLE,
|
||||
FF_COLORS_SYMBOL_DIAMOND,
|
||||
FF_COLORS_SYMBOL_SQUARE,
|
||||
|
@ -17,10 +17,9 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
{
|
||||
FFCPUResult cpu = {
|
||||
.temperature = FF_CPU_TEMP_UNSET,
|
||||
.frequencyMin = 0.0/0.0,
|
||||
.frequencyMax = 0.0/0.0,
|
||||
.frequencyBase = 0.0/0.0,
|
||||
.frequencyBiosLimit = 0.0/0.0,
|
||||
.frequencyMax = 0,
|
||||
.frequencyBase = 0,
|
||||
.frequencyBiosLimit = 0,
|
||||
.name = ffStrbufCreate(),
|
||||
.vendor = ffStrbufCreate(),
|
||||
};
|
||||
@ -72,13 +71,16 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
else if(cpu.coresOnline > 1)
|
||||
ffStrbufAppendF(&str, " (%u)", cpu.coresOnline);
|
||||
|
||||
double freq = cpu.frequencyBiosLimit;
|
||||
if(!(freq > 0.0000001))
|
||||
uint32_t freq = cpu.frequencyBiosLimit;
|
||||
if(freq == 0)
|
||||
freq = cpu.frequencyMax;
|
||||
if(!(freq > 0.0000001))
|
||||
if(freq == 0)
|
||||
freq = cpu.frequencyBase;
|
||||
if(freq > 0.0000001)
|
||||
ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, freq);
|
||||
if(freq > 0)
|
||||
{
|
||||
ffStrbufAppendS(&str, " @ ");
|
||||
ffParseFrequency(freq, &str);
|
||||
}
|
||||
|
||||
if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET
|
||||
{
|
||||
@ -90,19 +92,12 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
}
|
||||
else
|
||||
{
|
||||
char freqBase[32], freqMax[32], freqBioslimit[32];
|
||||
if (cpu.frequencyBase > 0)
|
||||
snprintf(freqBase, sizeof(freqBase), "%.*f", options->freqNdigits, cpu.frequencyBase);
|
||||
else
|
||||
freqBase[0] = 0;
|
||||
if (cpu.frequencyMax > 0)
|
||||
snprintf(freqMax, sizeof(freqMax), "%.*f", options->freqNdigits, cpu.frequencyMax);
|
||||
else
|
||||
freqMax[0] = 0;
|
||||
if (cpu.frequencyBiosLimit > 0)
|
||||
snprintf(freqBioslimit, sizeof(freqBioslimit), "%.*f", options->freqNdigits, cpu.frequencyBiosLimit);
|
||||
else
|
||||
freqBioslimit[0] = 0;
|
||||
FF_STRBUF_AUTO_DESTROY freqBase = ffStrbufCreate();
|
||||
ffParseFrequency(cpu.frequencyBase, &freqBase);
|
||||
FF_STRBUF_AUTO_DESTROY freqMax = ffStrbufCreate();
|
||||
ffParseFrequency(cpu.frequencyBase, &freqBase);
|
||||
FF_STRBUF_AUTO_DESTROY freqBioslimit = ffStrbufCreate();
|
||||
ffParseFrequency(cpu.frequencyBiosLimit, &freqBioslimit);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
|
||||
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig, &options->moduleArgs);
|
||||
@ -112,11 +107,11 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresPhysical, "cores-physical"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresLogical, "cores-logical"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresOnline, "cores-online"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, freqBase, "freq-base"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, freqMax, "freq-max"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &freqBase, "freq-base"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &freqMax, "freq-max"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr, "temperature"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &coreTypes, "core-types"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, freqBioslimit, "freq-bios-limit"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &freqBioslimit, "freq-bios-limit"},
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -135,12 +130,6 @@ bool ffParseCPUCommandOptions(FFCPUOptions* options, const char* key, const char
|
||||
if (ffTempsParseCommandOptions(key, subKey, value, &options->temp, &options->tempConfig))
|
||||
return true;
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "freq-ndigits"))
|
||||
{
|
||||
options->freqNdigits = (uint8_t) ffOptionParseUInt32(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "show-pe-core-count"))
|
||||
{
|
||||
options->showPeCoreCount = ffOptionParseBoolean(value);
|
||||
@ -168,7 +157,7 @@ void ffParseCPUJsonObject(FFCPUOptions* options, yyjson_val* module)
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "freqNdigits"))
|
||||
{
|
||||
options->freqNdigits = (uint8_t) yyjson_get_uint(val);
|
||||
ffPrintError(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "modules.CPU.freqNdigits has been moved to display.freq.ndigits");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -191,9 +180,6 @@ void ffGenerateCPUJsonConfig(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
|
||||
ffTempsGenerateJsonConfig(doc, module, defaultOptions.temp, defaultOptions.tempConfig, options->temp, options->tempConfig);
|
||||
|
||||
if (defaultOptions.freqNdigits != options->freqNdigits)
|
||||
yyjson_mut_obj_add_uint(doc, module, "freqNdigits", options->freqNdigits);
|
||||
|
||||
if (defaultOptions.showPeCoreCount != options->showPeCoreCount)
|
||||
yyjson_mut_obj_add_bool(doc, module, "showPeCoreCount", options->showPeCoreCount);
|
||||
}
|
||||
@ -202,10 +188,9 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
{
|
||||
FFCPUResult cpu = {
|
||||
.temperature = FF_CPU_TEMP_UNSET,
|
||||
.frequencyMin = 0.0/0.0,
|
||||
.frequencyMax = 0.0/0.0,
|
||||
.frequencyBase = 0.0/0.0,
|
||||
.frequencyBiosLimit = 0.0/0.0,
|
||||
.frequencyMax = 0,
|
||||
.frequencyBase = 0,
|
||||
.frequencyBiosLimit = 0,
|
||||
.name = ffStrbufCreate(),
|
||||
.vendor = ffStrbufCreate(),
|
||||
};
|
||||
@ -232,10 +217,9 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
yyjson_mut_obj_add_uint(doc, cores, "online", cpu.coresOnline);
|
||||
|
||||
yyjson_mut_val* frequency = yyjson_mut_obj_add_obj(doc, obj, "frequency");
|
||||
yyjson_mut_obj_add_real(doc, frequency, "base", cpu.frequencyBase);
|
||||
yyjson_mut_obj_add_real(doc, frequency, "max", cpu.frequencyMax);
|
||||
yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin);
|
||||
yyjson_mut_obj_add_real(doc, frequency, "biosLimit", cpu.frequencyBiosLimit);
|
||||
yyjson_mut_obj_add_uint(doc, frequency, "base", cpu.frequencyBase);
|
||||
yyjson_mut_obj_add_uint(doc, frequency, "max", cpu.frequencyMax);
|
||||
yyjson_mut_obj_add_uint(doc, frequency, "biosLimit", cpu.frequencyBiosLimit);
|
||||
|
||||
yyjson_mut_val* coreTypes = yyjson_mut_obj_add_arr(doc, obj, "coreTypes");
|
||||
for (uint32_t i = 0; i < sizeof (cpu.coreTypes) / sizeof (cpu.coreTypes[0]) && cpu.coreTypes[i].count > 0; i++)
|
||||
@ -260,11 +244,11 @@ void ffPrintCPUHelpFormat(void)
|
||||
"Physical core count - cores-physical",
|
||||
"Logical core count - cores-logical",
|
||||
"Online core count - cores-online",
|
||||
"Base frequency - freq-base",
|
||||
"Max frequency - freq-max",
|
||||
"Base frequency (formatted) - freq-base",
|
||||
"Max frequency (formatted) - freq-max",
|
||||
"Temperature (formatted) - temperature",
|
||||
"Logical core count grouped by frequency - core-types",
|
||||
"Bios limited frequency - freq-bios-limit",
|
||||
"Bios limited frequency (formatted) - freq-bios-limit",
|
||||
}));
|
||||
}
|
||||
|
||||
@ -284,7 +268,6 @@ void ffInitCPUOptions(FFCPUOptions* options)
|
||||
ffOptionInitModuleArg(&options->moduleArgs);
|
||||
options->temp = false;
|
||||
options->tempConfig = (FFColorRangeConfig) { 60, 80 };
|
||||
options->freqNdigits = 2;
|
||||
options->showPeCoreCount = false;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,5 @@ typedef struct FFCPUOptions
|
||||
|
||||
bool temp;
|
||||
FFColorRangeConfig tempConfig;
|
||||
uint8_t freqNdigits;
|
||||
bool showPeCoreCount;
|
||||
} FFCPUOptions;
|
||||
|
@ -4,7 +4,9 @@
|
||||
#include "modules/display/display.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_DISPLAY_NUM_FORMAT_ARGS 9
|
||||
#include <math.h>
|
||||
|
||||
#define FF_DISPLAY_NUM_FORMAT_ARGS 13
|
||||
|
||||
static int sortByNameAsc(FFDisplayResult* a, FFDisplayResult* b)
|
||||
{
|
||||
@ -96,35 +98,44 @@ void ffPrintDisplay(FFDisplayOptions* options)
|
||||
}));
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
double inch = sqrt(result->physicalWidth * result->physicalWidth + result->physicalHeight * result->physicalHeight) / 25.4;
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
|
||||
printf("%ix%i", result->width, result->height);
|
||||
ffStrbufAppendF(&buffer, "%ix%i", result->width, result->height);
|
||||
|
||||
if(result->refreshRate > 0)
|
||||
{
|
||||
if(options->preciseRefreshRate)
|
||||
printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0);
|
||||
ffStrbufAppendF(&buffer, " @ %g Hz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0);
|
||||
else
|
||||
printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5));
|
||||
ffStrbufAppendF(&buffer, " @ %i Hz", (uint32_t) (result->refreshRate + 0.5));
|
||||
}
|
||||
|
||||
if(
|
||||
result->scaledWidth > 0 && result->scaledWidth != result->width &&
|
||||
result->scaledHeight > 0 && result->scaledHeight != result->height)
|
||||
printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight);
|
||||
ffStrbufAppendF(&buffer, " (as %ix%i)", result->scaledWidth, result->scaledHeight);
|
||||
|
||||
if (inch > 0)
|
||||
ffStrbufAppendF(&buffer, " in %i″", (uint32_t) (inch + 0.5));
|
||||
|
||||
if(result->type != FF_DISPLAY_TYPE_UNKNOWN)
|
||||
fputs(result->type == FF_DISPLAY_TYPE_BUILTIN ? " [Built-in]" : " [External]", stdout);
|
||||
ffStrbufAppendS(&buffer, result->type == FF_DISPLAY_TYPE_BUILTIN ? " [Built-in]" : " [External]");
|
||||
|
||||
if(moduleIndex > 0 && result->primary)
|
||||
printf(" *");
|
||||
ffStrbufAppendS(&buffer, " *");
|
||||
|
||||
putchar('\n');
|
||||
ffStrbufPutTo(&buffer, stdout);
|
||||
ffStrbufClear(&buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
double ppi = sqrt(result->width * result->width + result->height * result->height) / inch;
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISPLAY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->width, "width"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->height, "height"},
|
||||
@ -135,6 +146,10 @@ void ffPrintDisplay(FFDisplayOptions* options)
|
||||
{FF_FORMAT_ARG_TYPE_STRING, displayType, "type"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->rotation, "rotation"},
|
||||
{FF_FORMAT_ARG_TYPE_BOOL, &result->primary, "is-primary"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->physicalWidth, "physical-width"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->physicalHeight, "physical-height"},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &inch, "inch"},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &ppi, "ppi"},
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -284,15 +299,28 @@ void ffGenerateDisplayJsonResult(FF_MAYBE_UNUSED FFDisplayOptions* options, yyjs
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, item, dsResult->displays)
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "width", item->width);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "height", item->height);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "id", item->id);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "primary", item->primary);
|
||||
|
||||
yyjson_mut_val* output = yyjson_mut_obj_add_obj(doc, obj, "output");
|
||||
yyjson_mut_obj_add_uint(doc, output, "width", item->width);
|
||||
yyjson_mut_obj_add_uint(doc, output, "height", item->height);
|
||||
|
||||
yyjson_mut_val* scaled = yyjson_mut_obj_add_obj(doc, obj, "scaled");
|
||||
yyjson_mut_obj_add_uint(doc, scaled, "width", item->scaledWidth);
|
||||
yyjson_mut_obj_add_uint(doc, scaled, "height", item->scaledHeight);
|
||||
|
||||
yyjson_mut_val* physical = yyjson_mut_obj_add_obj(doc, obj, "physical");
|
||||
yyjson_mut_obj_add_uint(doc, physical, "width", item->physicalWidth);
|
||||
yyjson_mut_obj_add_uint(doc, physical, "height", item->physicalHeight);
|
||||
|
||||
yyjson_mut_obj_add_real(doc, obj, "refreshRate", item->refreshRate);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "rotation", item->rotation);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "scaledHeight", item->scaledHeight);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "scaledWidth", item->scaledWidth);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "bitDepth", item->bitDepth);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "hdrEnabled", item->hdrEnabled);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "wcgEnabled", item->wcgEnabled);
|
||||
|
||||
switch (item->type)
|
||||
{
|
||||
case FF_DISPLAY_TYPE_BUILTIN:
|
||||
@ -320,6 +348,10 @@ void ffPrintDisplayHelpFormat(void)
|
||||
"Screen type (builtin, external or unknown) - type",
|
||||
"Screen rotation (in degrees) - rotation",
|
||||
"True if being the primary screen - is-primary",
|
||||
"Screen physical width (in millimeters) - physical-width",
|
||||
"Screen physical height (in millimeters) - physical-height",
|
||||
"Physical diagonal length in inches - inch",
|
||||
"Pixels per inch (PPI) - ppi",
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,11 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
if(gpu->coreCount != FF_GPU_CORE_COUNT_UNSET)
|
||||
ffStrbufAppendF(&output, " (%d)", gpu->coreCount);
|
||||
|
||||
if(gpu->frequency == gpu->frequency && gpu->frequency > 0 /* Inactive? */)
|
||||
ffStrbufAppendF(&output, " @ %.2f GHz", gpu->frequency);
|
||||
if(gpu->frequency > 0)
|
||||
{
|
||||
ffStrbufAppendS(&output, " @ ");
|
||||
ffParseFrequency(gpu->frequency, &output);
|
||||
}
|
||||
|
||||
if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET
|
||||
{
|
||||
@ -177,6 +180,7 @@ bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char
|
||||
{ "discrete", FF_GPU_TYPE_DISCRETE },
|
||||
{},
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ffPercentParseCommandOptions(key, subKey, value, &options->percent))
|
||||
|
@ -30,10 +30,9 @@ void ffPrintLoadavg(FFLoadavgOptions* options)
|
||||
{
|
||||
FFCPUResult cpu = {
|
||||
.temperature = FF_CPU_TEMP_UNSET,
|
||||
.frequencyMin = 0.0/0.0,
|
||||
.frequencyMax = 0.0/0.0,
|
||||
.frequencyBase = 0.0/0.0,
|
||||
.frequencyBiosLimit = 0.0/0.0,
|
||||
.frequencyMax = 0,
|
||||
.frequencyBase = 0,
|
||||
.frequencyBiosLimit = 0,
|
||||
.name = ffStrbufCreate(),
|
||||
.vendor = ffStrbufCreate(),
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define FF_MONITOR_NUM_FORMAT_ARGS 10
|
||||
#define FF_MONITOR_NUM_FORMAT_ARGS 11
|
||||
|
||||
void ffPrintMonitor(FFMonitorOptions* options)
|
||||
{
|
||||
@ -52,6 +52,8 @@ void ffPrintMonitor(FFMonitorOptions* options)
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
|
||||
printf("%ux%u px", display->width, display->height);
|
||||
if (display->refreshRate > 0)
|
||||
printf(" @ %.3f Hz", display->refreshRate);
|
||||
if (inch > 0)
|
||||
printf(" - %ux%u mm (%.2f inches, %.2f ppi)\n", display->physicalWidth, display->physicalHeight, inch, ppi);
|
||||
else
|
||||
@ -79,6 +81,7 @@ void ffPrintMonitor(FFMonitorOptions* options)
|
||||
{FF_FORMAT_ARG_TYPE_UINT16, &display->manufactureYear, "manufacture-year"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT16, &display->manufactureWeek, "manufacture-week"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, buf, "serial"},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, buf, "refresh-rate"},
|
||||
}));
|
||||
}
|
||||
|
||||
@ -153,6 +156,8 @@ void ffGenerateMonitorJsonResult(FF_MAYBE_UNUSED FFMonitorOptions* options, yyjs
|
||||
yyjson_mut_obj_add_uint(doc, physical, "height", item->physicalHeight);
|
||||
yyjson_mut_obj_add_uint(doc, physical, "width", item->physicalWidth);
|
||||
|
||||
yyjson_mut_obj_add_real(doc, obj, "refreshRate", item->refreshRate);
|
||||
|
||||
if (item->manufactureYear)
|
||||
{
|
||||
yyjson_mut_val* manufactureDate = yyjson_mut_obj_add_obj(doc, obj, "manufactureDate");
|
||||
@ -190,6 +195,7 @@ void ffPrintMonitorHelpFormat(void)
|
||||
"Year of manufacturing - manufacture-year",
|
||||
"Nth week of manufacturing in the year - manufacture-week",
|
||||
"Serial number - serial",
|
||||
"Maximum refresh rate in Hz - refresh-rate",
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -10,4 +10,5 @@ typedef struct FFSeparatorOptions
|
||||
|
||||
FFstrbuf string;
|
||||
FFstrbuf outputColor;
|
||||
uint32_t length;
|
||||
} FFSeparatorOptions;
|
||||
|
@ -34,6 +34,23 @@ static inline uint32_t getWcsWidth(const FFstrbuf* mbstr, wchar_t* wstr, mbstate
|
||||
|
||||
void ffPrintSeparator(FFSeparatorOptions* options)
|
||||
{
|
||||
ffLogoPrintLine();
|
||||
|
||||
if (options->length > 0)
|
||||
{
|
||||
if(__builtin_expect(options->string.length == 1, 1))
|
||||
ffPrintCharTimes(options->string.chars[0], options->length);
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < options->length; i++)
|
||||
{
|
||||
fputs(options->string.chars, stdout);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
mbstate_t state = {};
|
||||
bool fqdn = instance.config.modules.title.fqdn;
|
||||
@ -45,7 +62,6 @@ void ffPrintSeparator(FFSeparatorOptions* options)
|
||||
uint32_t titleLength = 1 // @
|
||||
+ getWcsWidth(&platform->userName, wstr, &state) // user name
|
||||
+ (fqdn ? platform->hostName.length : ffStrbufFirstIndexC(&platform->hostName, '.')); // host name
|
||||
ffLogoPrintLine();
|
||||
|
||||
if(options->outputColor.length && !instance.config.display.pipe)
|
||||
ffPrintColor(&options->outputColor);
|
||||
@ -112,6 +128,12 @@ bool ffParseSeparatorCommandOptions(FFSeparatorOptions* options, const char* key
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "length"))
|
||||
{
|
||||
options->length = ffOptionParseUInt32(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -137,6 +159,12 @@ void ffParseSeparatorJsonObject(FFSeparatorOptions* options, yyjson_val* module)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ffStrEndsWithIgnCase(key, "length"))
|
||||
{
|
||||
options->length = (uint32_t) yyjson_get_uint(val);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffPrintError(FF_SEPARATOR_MODULE_NAME, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "Unknown JSON key %s", key);
|
||||
}
|
||||
}
|
||||
@ -164,6 +192,8 @@ void ffInitSeparatorOptions(FFSeparatorOptions* options)
|
||||
ffGenerateSeparatorJsonConfig
|
||||
);
|
||||
ffStrbufInitStatic(&options->string, "-");
|
||||
ffStrbufInit(&options->outputColor);
|
||||
options->length = 0;
|
||||
}
|
||||
|
||||
void ffDestroySeparatorOptions(FFSeparatorOptions* options)
|
||||
|
@ -61,17 +61,7 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
else if (ffStrEqualsIgnCase(key, "brightColor"))
|
||||
options->brightColor = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "binaryPrefix"))
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "iec", FF_BINARY_PREFIX_TYPE_IEC },
|
||||
{ "si", FF_BINARY_PREFIX_TYPE_SI },
|
||||
{ "jedec", FF_BINARY_PREFIX_TYPE_JEDEC },
|
||||
{},
|
||||
});
|
||||
if (error) return error;
|
||||
options->binaryPrefixType = (FFBinaryPrefixType) value;
|
||||
}
|
||||
return "`display.binaryPrefix` has been renamed to `display.size.binaryPrefix`. Sorry for another break change.";
|
||||
else if (ffStrEqualsIgnCase(key, "size"))
|
||||
{
|
||||
if (!yyjson_is_obj(val))
|
||||
@ -97,6 +87,20 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
options->sizeMaxPrefix = (uint8_t) value;
|
||||
}
|
||||
|
||||
yyjson_val* binaryPrefix = yyjson_obj_get(val, "binaryPrefix");
|
||||
if (binaryPrefix)
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(binaryPrefix, &value, (FFKeyValuePair[]) {
|
||||
{ "iec", FF_SIZE_BINARY_PREFIX_TYPE_IEC },
|
||||
{ "si", FF_SIZE_BINARY_PREFIX_TYPE_SI },
|
||||
{ "jedec", FF_SIZE_BINARY_PREFIX_TYPE_JEDEC },
|
||||
{},
|
||||
});
|
||||
if (error) return error;
|
||||
options->sizeBinaryPrefix = (FFSizeBinaryPrefixType) value;
|
||||
}
|
||||
|
||||
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
|
||||
if (ndigits) options->sizeNdigits = (uint8_t) yyjson_get_uint(ndigits);
|
||||
}
|
||||
@ -199,8 +203,23 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
options->noBuffer = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "keyWidth"))
|
||||
options->keyWidth = (uint32_t) yyjson_get_uint(val);
|
||||
else if (ffStrEqualsIgnCase(key, "tsVersion"))
|
||||
return "display.tsVersion has been renamed to general.detectVersion";
|
||||
else if (ffStrEqualsIgnCase(key, "constants"))
|
||||
{
|
||||
if (!yyjson_is_arr(val))
|
||||
return "display.constants must be an array";
|
||||
yyjson_val* item;
|
||||
size_t idx, max;
|
||||
yyjson_arr_foreach(val, idx, max, item)
|
||||
ffStrbufInitS(ffListAdd(&options->constants), yyjson_get_str(item));
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "freq"))
|
||||
{
|
||||
if (!yyjson_is_obj(val))
|
||||
return "display.freq must be an object";
|
||||
|
||||
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
|
||||
if (ndigits) options->freqNdigits = (int8_t) yyjson_get_int(ndigits);
|
||||
}
|
||||
else
|
||||
return "Unknown display property";
|
||||
}
|
||||
@ -273,29 +292,40 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
|
||||
options->brightColor = ffOptionParseBoolean(value);
|
||||
else if(ffStrEqualsIgnCase(key, "--binary-prefix"))
|
||||
{
|
||||
options->binaryPrefixType = (FFBinaryPrefixType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "iec", FF_BINARY_PREFIX_TYPE_IEC },
|
||||
{ "si", FF_BINARY_PREFIX_TYPE_SI },
|
||||
{ "jedec", FF_BINARY_PREFIX_TYPE_JEDEC },
|
||||
{}
|
||||
});
|
||||
fprintf(stderr, "--binary-prefix has been renamed to --size-binary-prefix\n");
|
||||
exit(477);
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "--size-ndigits"))
|
||||
options->sizeNdigits = (uint8_t) ffOptionParseUInt32(key, value);
|
||||
else if(ffStrEqualsIgnCase(key, "--size-max-prefix"))
|
||||
else if(ffStrStartsWithIgnCase(key, "--size-"))
|
||||
{
|
||||
options->sizeMaxPrefix = (uint8_t) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "B", 0 },
|
||||
{ "kB", 1 },
|
||||
{ "MB", 2 },
|
||||
{ "GB", 3 },
|
||||
{ "TB", 4 },
|
||||
{ "PB", 5 },
|
||||
{ "EB", 6 },
|
||||
{ "ZB", 7 },
|
||||
{ "YB", 8 },
|
||||
{}
|
||||
});
|
||||
const char* subkey = key + strlen("--size-");
|
||||
if (ffStrEqualsIgnCase(subkey, "binary-prefix"))
|
||||
{
|
||||
options->sizeBinaryPrefix = (FFSizeBinaryPrefixType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "iec", FF_SIZE_BINARY_PREFIX_TYPE_IEC },
|
||||
{ "si", FF_SIZE_BINARY_PREFIX_TYPE_SI },
|
||||
{ "jedec", FF_SIZE_BINARY_PREFIX_TYPE_JEDEC },
|
||||
{}
|
||||
});
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(subkey, "ndigits"))
|
||||
options->sizeNdigits = (uint8_t) ffOptionParseUInt32(key, value);
|
||||
else if (ffStrEqualsIgnCase(subkey, "max-prefix"))
|
||||
{
|
||||
options->sizeMaxPrefix = (uint8_t) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "B", 0 },
|
||||
{ "kB", 1 },
|
||||
{ "MB", 2 },
|
||||
{ "GB", 3 },
|
||||
{ "TB", 4 },
|
||||
{ "PB", 5 },
|
||||
{ "EB", 6 },
|
||||
{ "ZB", 7 },
|
||||
{ "YB", 8 },
|
||||
{}
|
||||
});
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if(ffStrStartsWithIgnCase(key, "--temp-"))
|
||||
{
|
||||
@ -357,6 +387,12 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if(ffStrStartsWithIgnCase(key, "--freq-"))
|
||||
{
|
||||
const char* subkey = key + strlen("--freq-");
|
||||
if(ffStrEqualsIgnCase(subkey, "ndigits"))
|
||||
options->freqNdigits = (int8_t) ffOptionParseInt32(key, value);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
@ -381,7 +417,7 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options)
|
||||
#endif
|
||||
|
||||
options->hideCursor = false;
|
||||
options->binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
|
||||
options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_IEC;
|
||||
options->sizeNdigits = 2;
|
||||
options->sizeMaxPrefix = UINT8_MAX;
|
||||
options->stat = false;
|
||||
@ -404,6 +440,9 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options)
|
||||
ffStrbufInitStatic(&options->percentColorGreen, FF_COLOR_FG_GREEN);
|
||||
ffStrbufInitStatic(&options->percentColorYellow, instance.state.terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||
ffStrbufInitStatic(&options->percentColorRed, instance.state.terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||
options->freqNdigits = 2;
|
||||
|
||||
ffListInit(&options->constants, sizeof(FFstrbuf));
|
||||
}
|
||||
|
||||
void ffOptionsDestroyDisplay(FFOptionsDisplay* options)
|
||||
@ -415,6 +454,9 @@ void ffOptionsDestroyDisplay(FFOptionsDisplay* options)
|
||||
ffStrbufDestroy(&options->keyValueSeparator);
|
||||
ffStrbufDestroy(&options->barCharElapsed);
|
||||
ffStrbufDestroy(&options->barCharTotal);
|
||||
FF_LIST_FOR_EACH(FFstrbuf, item, options->constants)
|
||||
ffStrbufDestroy(item);
|
||||
ffListDestroy(&options->constants);
|
||||
}
|
||||
|
||||
void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_doc* doc)
|
||||
@ -464,23 +506,6 @@ void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_do
|
||||
if (options->brightColor != defaultOptions.brightColor)
|
||||
yyjson_mut_obj_add_bool(doc, obj, "brightColor", options->brightColor);
|
||||
|
||||
if (options->binaryPrefixType != defaultOptions.binaryPrefixType)
|
||||
{
|
||||
switch (options->binaryPrefixType)
|
||||
{
|
||||
case FF_BINARY_PREFIX_TYPE_IEC:
|
||||
yyjson_mut_obj_add_str(doc, obj, "binaryPrefix", "iec");
|
||||
break;
|
||||
case FF_BINARY_PREFIX_TYPE_SI:
|
||||
yyjson_mut_obj_add_str(doc, obj, "binaryPrefix", "si");
|
||||
break;
|
||||
case FF_BINARY_PREFIX_TYPE_JEDEC:
|
||||
yyjson_mut_obj_add_str(doc, obj, "binaryPrefix", "jedec");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
yyjson_mut_val* size = yyjson_mut_obj(doc);
|
||||
if (options->sizeNdigits != defaultOptions.sizeNdigits)
|
||||
@ -499,6 +524,21 @@ void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_do
|
||||
"YB",
|
||||
})[options->sizeMaxPrefix]);
|
||||
}
|
||||
if (options->sizeBinaryPrefix != defaultOptions.sizeBinaryPrefix)
|
||||
{
|
||||
switch (options->sizeBinaryPrefix)
|
||||
{
|
||||
case FF_SIZE_BINARY_PREFIX_TYPE_IEC:
|
||||
yyjson_mut_obj_add_str(doc, size, "binaryPrefix", "iec");
|
||||
break;
|
||||
case FF_SIZE_BINARY_PREFIX_TYPE_SI:
|
||||
yyjson_mut_obj_add_str(doc, size, "binaryPrefix", "si");
|
||||
break;
|
||||
case FF_SIZE_BINARY_PREFIX_TYPE_JEDEC:
|
||||
yyjson_mut_obj_add_str(doc, size, "binaryPrefix", "jedec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (yyjson_mut_obj_size(size) > 0)
|
||||
yyjson_mut_obj_add_val(doc, obj, "size", size);
|
||||
}
|
||||
@ -581,6 +621,14 @@ void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_do
|
||||
if (options->keyWidth != defaultOptions.keyWidth)
|
||||
yyjson_mut_obj_add_uint(doc, obj, "keyWidth", options->keyWidth);
|
||||
|
||||
{
|
||||
yyjson_mut_val* freq = yyjson_mut_obj(doc);
|
||||
if (options->freqNdigits != defaultOptions.freqNdigits)
|
||||
yyjson_mut_obj_add_int(doc, freq, "ndigits", options->freqNdigits);
|
||||
if (yyjson_mut_obj_size(freq) > 0)
|
||||
yyjson_mut_obj_add_val(doc, obj, "freq", freq);
|
||||
}
|
||||
|
||||
if (yyjson_mut_obj_size(obj) > 0)
|
||||
yyjson_mut_obj_add_val(doc, doc->root, "display", obj);
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
typedef enum FFBinaryPrefixType
|
||||
typedef enum FFSizeBinaryPrefixType
|
||||
{
|
||||
FF_BINARY_PREFIX_TYPE_IEC, // 1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)
|
||||
FF_BINARY_PREFIX_TYPE_SI, // 1000 Bytes = 1 KB, 1000 KB = 1 MB, ...
|
||||
FF_BINARY_PREFIX_TYPE_JEDEC, // 1024 Bytes = 1 kB, 1024 kB = 1 MB, ...
|
||||
} FFBinaryPrefixType;
|
||||
FF_SIZE_BINARY_PREFIX_TYPE_IEC, // 1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)
|
||||
FF_SIZE_BINARY_PREFIX_TYPE_SI, // 1000 Bytes = 1 KB, 1000 KB = 1 MB, ...
|
||||
FF_SIZE_BINARY_PREFIX_TYPE_JEDEC, // 1024 Bytes = 1 kB, 1024 kB = 1 MB, ...
|
||||
} FFSizeBinaryPrefixType;
|
||||
|
||||
typedef enum FFTemperatureUnit
|
||||
{
|
||||
@ -33,7 +33,7 @@ typedef struct FFOptionsDisplay
|
||||
bool showErrors;
|
||||
bool disableLinewrap;
|
||||
bool hideCursor;
|
||||
FFBinaryPrefixType binaryPrefixType;
|
||||
FFSizeBinaryPrefixType sizeBinaryPrefix;
|
||||
uint8_t sizeNdigits;
|
||||
uint8_t sizeMaxPrefix;
|
||||
FFTemperatureUnit tempUnit;
|
||||
@ -53,6 +53,8 @@ typedef struct FFOptionsDisplay
|
||||
FFstrbuf percentColorRed;
|
||||
bool noBuffer;
|
||||
uint32_t keyWidth;
|
||||
int8_t freqNdigits;
|
||||
FFlist constants; // list of FFstrbuf
|
||||
} FFOptionsDisplay;
|
||||
|
||||
const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_val* root);
|
||||
|
@ -292,21 +292,22 @@ void ffStrbufTrimRightSpace(FFstrbuf* strbuf)
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
}
|
||||
|
||||
void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex)
|
||||
bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex)
|
||||
{
|
||||
if(startIndex > strbuf->length || startIndex >= endIndex)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(endIndex > strbuf->length)
|
||||
{
|
||||
ffStrbufSubstrBefore(strbuf, startIndex);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
ffStrbufEnsureFree(strbuf, 0);
|
||||
memmove(strbuf->chars + startIndex, strbuf->chars + endIndex, strbuf->length - endIndex);
|
||||
strbuf->length -= (endIndex - startIndex);
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str)
|
||||
@ -362,28 +363,29 @@ void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace)
|
||||
*current_pos = replace;
|
||||
}
|
||||
|
||||
void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index)
|
||||
bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index)
|
||||
{
|
||||
if(strbuf->length <= index)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(strbuf->allocated == 0)
|
||||
{
|
||||
//static string
|
||||
ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
strbuf->length = index;
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index)
|
||||
bool ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index)
|
||||
{
|
||||
if(index >= strbuf->length)
|
||||
{
|
||||
ffStrbufClear(strbuf);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(strbuf->allocated == 0)
|
||||
@ -391,36 +393,45 @@ void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index)
|
||||
//static string
|
||||
strbuf->length -= index + 1;
|
||||
strbuf->chars += index + 1;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
memmove(strbuf->chars, strbuf->chars + index + 1, strbuf->length - index - 1);
|
||||
strbuf->length -= (index + 1);
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c)
|
||||
bool ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c)
|
||||
{
|
||||
uint32_t index = ffStrbufFirstIndexC(strbuf, c);
|
||||
if(index < strbuf->length)
|
||||
ffStrbufSubstrAfter(strbuf, index);
|
||||
if(index >= strbuf->length)
|
||||
return false;
|
||||
ffStrbufSubstrAfter(strbuf, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str)
|
||||
bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str)
|
||||
{
|
||||
if(*str == '\0')
|
||||
return;
|
||||
return false;
|
||||
|
||||
uint32_t index = ffStrbufFirstIndexS(strbuf, str) + (uint32_t) strlen(str) - 1; // -1, because firstIndexS is already pointing to str[0], we want to add only the remaining length
|
||||
if(index < strbuf->length)
|
||||
ffStrbufSubstrAfter(strbuf, index);
|
||||
if(index >= strbuf->length)
|
||||
return false;
|
||||
|
||||
ffStrbufSubstrAfter(strbuf, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c)
|
||||
bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c)
|
||||
{
|
||||
uint32_t index = ffStrbufLastIndexC(strbuf, c);
|
||||
if(index < strbuf->length)
|
||||
ffStrbufSubstrAfter(strbuf, index);
|
||||
if(index >= strbuf->length)
|
||||
return false;
|
||||
|
||||
ffStrbufSubstrAfter(strbuf, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c)
|
||||
@ -448,10 +459,13 @@ bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c)
|
||||
bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c)
|
||||
{
|
||||
if(!ffStrbufEndsWithC(strbuf, c))
|
||||
ffStrbufAppendC(strbuf, c);
|
||||
if(ffStrbufEndsWithC(strbuf, c))
|
||||
return false;
|
||||
|
||||
ffStrbufAppendC(strbuf, c);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file)
|
||||
|
@ -56,7 +56,7 @@ void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufTrimRightSpace(FFstrbuf* strbuf);
|
||||
|
||||
void ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex);
|
||||
bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endIndex);
|
||||
void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str);
|
||||
void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]);
|
||||
|
||||
@ -67,17 +67,18 @@ FF_C_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t
|
||||
|
||||
void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace);
|
||||
|
||||
void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index);
|
||||
void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index); // Not including the index
|
||||
void ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c);
|
||||
void ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str);
|
||||
void ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c);
|
||||
// Returns true if the strbuf is modified
|
||||
bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index);
|
||||
bool ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index); // Not including the index
|
||||
bool ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c);
|
||||
bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str);
|
||||
bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c);
|
||||
|
||||
FF_C_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c);
|
||||
|
||||
bool ffStrbufRemoveIgnCaseEndS(FFstrbuf* strbuf, const char* end);
|
||||
|
||||
void ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
|
||||
bool ffStrbufEnsureEndsWithC(FFstrbuf* strbuf, char c);
|
||||
|
||||
void ffStrbufWriteTo(const FFstrbuf* strbuf, FILE* file);
|
||||
void ffStrbufPutTo(const FFstrbuf* strbuf, FILE* file);
|
||||
@ -383,14 +384,14 @@ static inline FF_C_NODISCARD uint32_t ffStrbufLastIndexC(const FFstrbuf* strbuf,
|
||||
return ffStrbufPreviousIndexC(strbuf, strbuf->length - 1, c);
|
||||
}
|
||||
|
||||
static inline void ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c)
|
||||
static inline bool ffStrbufSubstrBeforeFirstC(FFstrbuf* strbuf, char c)
|
||||
{
|
||||
ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c));
|
||||
return ffStrbufSubstrBefore(strbuf, ffStrbufFirstIndexC(strbuf, c));
|
||||
}
|
||||
|
||||
static inline void ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c)
|
||||
static inline bool ffStrbufSubstrBeforeLastC(FFstrbuf* strbuf, char c)
|
||||
{
|
||||
ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c));
|
||||
return ffStrbufSubstrBefore(strbuf, ffStrbufLastIndexC(strbuf, c));
|
||||
}
|
||||
|
||||
static inline FF_C_NODISCARD bool ffStrbufStartsWithC(const FFstrbuf* strbuf, char c)
|
||||
|
@ -93,12 +93,26 @@ int main(void)
|
||||
|
||||
//substr
|
||||
|
||||
ffStrbufSubstrBefore(&strbuf, 9);
|
||||
VERIFY(ffStrbufSubstrBefore(&strbuf, 9));
|
||||
VERIFY(strbuf.length == 9);
|
||||
VERIFY(strbuf.allocated >= 110);
|
||||
VERIFY(strbuf.chars[strbuf.length] == 0);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "123456789"));
|
||||
|
||||
VERIFY(!ffStrbufSubstrBeforeFirstC(&strbuf, '0'));
|
||||
VERIFY(!ffStrbufSubstrBeforeLastC(&strbuf, '0'));
|
||||
VERIFY(!ffStrbufSubstrAfterFirstC(&strbuf, '0'));
|
||||
VERIFY(!ffStrbufSubstrAfterLastC(&strbuf, '0'));
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "123456789"));
|
||||
|
||||
VERIFY(ffStrbufSubstrBeforeFirstC(&strbuf, '9'));
|
||||
VERIFY(ffStrbufSubstrBeforeLastC(&strbuf, '8'));
|
||||
VERIFY(ffStrbufSubstrAfterFirstC(&strbuf, '1'));
|
||||
VERIFY(ffStrbufSubstrAfterLastC(&strbuf, '2'));
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "34567"));
|
||||
|
||||
ffStrbufSetS(&strbuf, "123456789");
|
||||
|
||||
//startsWithC
|
||||
|
||||
VERIFY(ffStrbufStartsWithC(&strbuf, '1'));
|
||||
@ -313,7 +327,7 @@ int main(void)
|
||||
|
||||
//ffStrbufCreateStatic / Substr
|
||||
ffStrbufInitStatic(&strbuf, "__TEST__");
|
||||
ffStrbufRemoveSubstr(&strbuf, 0, 6);
|
||||
VERIFY(ffStrbufRemoveSubstr(&strbuf, 0, 6));
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "__"));
|
||||
VERIFY(strbuf.length == 2);
|
||||
VERIFY(strbuf.allocated > 0);
|
||||
@ -321,7 +335,7 @@ int main(void)
|
||||
|
||||
//ffStrbufCreateStatic / Substr
|
||||
ffStrbufInitStatic(&strbuf, "__TEST__");
|
||||
ffStrbufRemoveSubstr(&strbuf, 2, 8);
|
||||
VERIFY(ffStrbufRemoveSubstr(&strbuf, 2, 8));
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "__"));
|
||||
VERIFY(strbuf.length == 2);
|
||||
VERIFY(strbuf.allocated > 0);
|
||||
@ -329,13 +343,13 @@ int main(void)
|
||||
|
||||
//ffStrbufCreateStatic / Substr
|
||||
ffStrbufInitStatic(&strbuf, "__TEST__");
|
||||
ffStrbufRemoveSubstr(&strbuf, 2, 6);
|
||||
VERIFY(ffStrbufRemoveSubstr(&strbuf, 2, 6));
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "____"));
|
||||
VERIFY(strbuf.length == 4);
|
||||
VERIFY(strbuf.allocated > 0);
|
||||
ffStrbufDestroy(&strbuf);
|
||||
|
||||
//ffStrbufCreateStatic / Substr
|
||||
//ffStrbufCreateStatic / ReplaceAllC
|
||||
ffStrbufInitStatic(&strbuf, "__TEST__");
|
||||
ffStrbufReplaceAllC(&strbuf, '_', '-');
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "--TEST--"));
|
||||
@ -403,5 +417,5 @@ int main(void)
|
||||
ffStrbufDestroy(&strbuf);
|
||||
|
||||
//Success
|
||||
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
puts("\e[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user