mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a9f43ff466 | |||
| 924d78d3c4 | |||
| fa92bb84ae | |||
| 288d25e17c | |||
| 610fc2ea36 | |||
| 716c0e2b5c | |||
| 945aed7160 | |||
| 1d4d68f6e0 | |||
| 3e1167260d | |||
| 0130f610e9 | |||
| 94941daf4f | |||
| 2bbd723321 | |||
| 608382109c | |||
| bdc5174f68 | |||
| bc869f1be9 | |||
| dc69e44829 | |||
| d236850119 | |||
| 60ec8c9097 | |||
| 42e7a7d2f7 | |||
| e766809e3a | |||
| cb1f0300b9 | |||
| f2a29309f3 | |||
| 6e7b4bab75 | |||
| b4f39e251c | |||
| af6196fe6e | |||
| bca56b2049 | |||
| f4401f172e | |||
| c11b88fee5 | |||
| 88b1b558d7 | |||
| ba6cdc77c9 | |||
| b952772902 | |||
| 7a322154fa | |||
| 0b6ca158ea | |||
| 100cd9a72b | |||
| 98fb810f1f | |||
| c613e558fd | |||
| c324f83826 |
@@ -1,3 +1,19 @@
|
||||
# 2.56.1
|
||||
|
||||
Features:
|
||||
* Improves compatibility with KDE Plasma 6.5 (#2093, Display)
|
||||
* Adds a `tempSensor` option to specify the sensor name used for CPU temperature detection (CPU)
|
||||
* Example: `{ "type": "cpu", "tempSensor": "hwmon0" /* Use /sys/class/hwmon/hwmon0 for temperature detection */ }`
|
||||
* Refines Memory usage detection on macOS to match Activity Monitor more closely (Memory, macOS)
|
||||
* Minor optimizations
|
||||
|
||||
Bugfixes:
|
||||
* Fixes cache line size detection (CPU, macOS)
|
||||
|
||||
Logos:
|
||||
* Removes Opak
|
||||
* Updates GXDE
|
||||
|
||||
# 2.56.0
|
||||
|
||||
Features:
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.56.0
|
||||
VERSION 2.56.1
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
[](https://deepwiki.com/fastfetch-cli/fastfetch)
|
||||
[](README-cn.md)
|
||||
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and SunOS.
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and illumos (SunOS).
|
||||
|
||||
<img src="screenshots/example1.png" width="49%" align="left" />
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
||||
|
||||
Vendored
+12
@@ -1,3 +1,15 @@
|
||||
fastfetch (2.56.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||
|
||||
* Update to 2.56.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 18 Dec 2025 14:57:36 +0800
|
||||
|
||||
fastfetch (2.56.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||
|
||||
* Update to 2.56.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 08 Dec 2025 09:21:58 +0800
|
||||
|
||||
fastfetch (2.55.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
|
||||
|
||||
* Update to 2.55.1
|
||||
|
||||
@@ -1880,6 +1880,10 @@
|
||||
"temp": {
|
||||
"$ref": "#/$defs/temperature"
|
||||
},
|
||||
"tempSensor": {
|
||||
"description": "Set the temperature sensor to use for CPU temperature detection\n* Linux: `hwmon` or `thermal` path name (eg. `hwmon0`, `thermal_zone0)`\n* macOS: SMC sensor key (eg. `Tp01`)\n* Windows: thermal zone key (eg. `\\_TZ.CPUZ`)\n* FreeBSD: sysctl key (eg. `dev.cpu.0.temperature`)\n* NetBSD: sysmon sensor key (eg. `coretemp0`)",
|
||||
"type": "string"
|
||||
},
|
||||
"showPeCoreCount": {
|
||||
"description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
|
||||
"type": "boolean",
|
||||
|
||||
@@ -83,6 +83,13 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
|
||||
FF_C_NONNULL(2, 3)
|
||||
bool ffAppendFileBufferRelative(FFNativeFD dfd, const char* fileName, FFstrbuf* buffer);
|
||||
|
||||
FF_C_NONNULL(2)
|
||||
static inline bool ffReadFDBuffer(FFNativeFD fd, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufClear(buffer);
|
||||
return ffAppendFDBuffer(fd, buffer);
|
||||
}
|
||||
|
||||
FF_C_NONNULL(1, 2)
|
||||
static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
@@ -254,4 +261,5 @@ bool ffRemoveFile(const char* fileName);
|
||||
#ifdef _WIN32
|
||||
// Only O_RDONLY is supported
|
||||
HANDLE openat(HANDLE dfd, const char* fileName, bool directory);
|
||||
HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory);
|
||||
#endif
|
||||
|
||||
+35
-18
@@ -3,8 +3,8 @@
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "util/windows/nt.h"
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
@@ -102,31 +102,48 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
return ffAppendFDBuffer(handle, buffer);
|
||||
}
|
||||
|
||||
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
|
||||
HANDLE openatW(HANDLE dfd, const wchar_t* fileName, uint16_t fileNameLen, bool directory)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
UNICODE_STRING fileNameW;
|
||||
ret = RtlAnsiStringToUnicodeString(&fileNameW, &(ANSI_STRING) {
|
||||
.Length = (USHORT) strlen(fileName),
|
||||
.Buffer = (PCHAR) fileName
|
||||
}, TRUE);
|
||||
if (!NT_SUCCESS(ret)) return INVALID_HANDLE_VALUE;
|
||||
assert(fileNameLen <= 0x7FFF);
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE hFile;
|
||||
HANDLE hFile;
|
||||
IO_STATUS_BLOCK iosb = {};
|
||||
ret = NtOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
|
||||
.Length = sizeof(OBJECT_ATTRIBUTES),
|
||||
.RootDirectory = dfd,
|
||||
.ObjectName = &fileNameW,
|
||||
}, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE));
|
||||
RtlFreeUnicodeString(&fileNameW);
|
||||
|
||||
if(!NT_SUCCESS(ret) || iosb.Information != FILE_OPENED)
|
||||
if(!NT_SUCCESS(NtOpenFile(&hFile,
|
||||
(directory ? FILE_LIST_DIRECTORY | FILE_TRAVERSE : FILE_READ_DATA | FILE_READ_EA) | FILE_READ_ATTRIBUTES | SYNCHRONIZE, &(OBJECT_ATTRIBUTES) {
|
||||
.Length = sizeof(OBJECT_ATTRIBUTES),
|
||||
.RootDirectory = dfd,
|
||||
.ObjectName = &(UNICODE_STRING) {
|
||||
.Buffer = (PWSTR) fileName,
|
||||
.Length = fileNameLen * (USHORT) sizeof(wchar_t),
|
||||
.MaximumLength = (fileNameLen + 1) * (USHORT) sizeof(wchar_t),
|
||||
},
|
||||
.Attributes = OBJ_CASE_INSENSITIVE,
|
||||
},
|
||||
&iosb,
|
||||
FILE_SHARE_READ | (directory ? FILE_SHARE_WRITE | FILE_SHARE_DELETE : 0),
|
||||
FILE_SYNCHRONOUS_IO_NONALERT | (directory ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)
|
||||
)))
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
return hFile;
|
||||
}
|
||||
|
||||
HANDLE openat(HANDLE dfd, const char* fileName, bool directory)
|
||||
{
|
||||
wchar_t fileNameW[MAX_PATH];
|
||||
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, fileName, -1, fileNameW, ARRAY_SIZE(fileNameW));
|
||||
if (len == 0) return INVALID_HANDLE_VALUE;
|
||||
// Implies `fileNameW[len] = L'\0';` and `len` includes the null terminator
|
||||
|
||||
for (int i = 0; i < len - 1; ++i)
|
||||
{
|
||||
if (fileNameW[i] == L'/')
|
||||
fileNameW[i] = L'\\';
|
||||
}
|
||||
|
||||
return openatW(dfd, fileNameW, (uint16_t)(len - 1), directory);
|
||||
}
|
||||
|
||||
bool ffAppendFileBufferRelative(HANDLE dfd, const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
HANDLE FF_AUTO_CLOSE_FD fd = openat(dfd, fileName, false);
|
||||
|
||||
@@ -41,7 +41,7 @@ static const char* detectWithBacklight(FFlist* result)
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
ffStrbufSubstrBeforeLastC(&backlightDir, '/');
|
||||
ffStrbufAppendS(&backlightDir, "/device");
|
||||
ffStrbufInitA(&brightness->name, PATH_MAX + 1);
|
||||
ffStrbufInitA(&brightness->name, PATH_MAX);
|
||||
if(realpath(backlightDir.chars, brightness->name.chars))
|
||||
{
|
||||
ffStrbufRecalculateLength(&brightness->name);
|
||||
|
||||
@@ -3,26 +3,34 @@
|
||||
#include "util/apple/smc_temps.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
static double detectCpuTemp(const FFCPUOptions* options, const FFstrbuf* cpuName)
|
||||
{
|
||||
double result = 0;
|
||||
|
||||
const char* error = NULL;
|
||||
if (ffStrbufStartsWithS(cpuName, "Apple M"))
|
||||
{
|
||||
switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10))
|
||||
{
|
||||
case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break;
|
||||
case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break;
|
||||
case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break;
|
||||
case 4: error = ffDetectSmcTemps(FF_TEMP_CPU_M4X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon CPU";
|
||||
}
|
||||
}
|
||||
else // PPC?
|
||||
error = ffDetectSmcTemps(FF_TEMP_CPU_X64, &result);
|
||||
|
||||
if(error)
|
||||
if (options->tempSensor.length)
|
||||
{
|
||||
error = ffDetectSmcSpecificTemp(options->tempSensor.chars, &result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ffStrbufStartsWithS(cpuName, "Apple M"))
|
||||
{
|
||||
switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10))
|
||||
{
|
||||
case 1: error = ffDetectSmcTemps(FF_TEMP_CPU_M1X, &result); break;
|
||||
case 2: error = ffDetectSmcTemps(FF_TEMP_CPU_M2X, &result); break;
|
||||
case 3: error = ffDetectSmcTemps(FF_TEMP_CPU_M3X, &result); break;
|
||||
case 4: error = ffDetectSmcTemps(FF_TEMP_CPU_M4X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon CPU";
|
||||
}
|
||||
}
|
||||
else // PPC?
|
||||
error = ffDetectSmcTemps(FF_TEMP_CPU_X64, &result);
|
||||
}
|
||||
|
||||
if (error)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
return result;
|
||||
@@ -130,7 +138,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
detectFrequency(cpu);
|
||||
if (options->showPeCoreCount) detectCoreCount(cpu);
|
||||
|
||||
cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET;
|
||||
cpu->temperature = options->temp ? detectCpuTemp(options, &cpu->name) : FF_CPU_TEMP_UNSET;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+20
-20
@@ -8,22 +8,26 @@
|
||||
#define FF_HAVE_CPUSET 1
|
||||
#endif
|
||||
|
||||
static const char* detectCpuTemp(double* current)
|
||||
static const char* detectCpuTemp(const FFCPUOptions* options, double* current)
|
||||
{
|
||||
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
|
||||
if (temp == -999999)
|
||||
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
|
||||
|
||||
// In tenth of degrees Kelvin
|
||||
*current = (double) temp / 10 - 273.15;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectThermalTemp(double* current)
|
||||
{
|
||||
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
|
||||
if (temp == -999999)
|
||||
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
|
||||
int temp;
|
||||
if (options->tempSensor.length > 0)
|
||||
{
|
||||
temp = ffSysctlGetInt(options->tempSensor.chars, -999999);
|
||||
if (temp == -999999)
|
||||
return "ffSysctlGetInt(options->tempSensor) failed";
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
|
||||
if (temp == -999999)
|
||||
{
|
||||
// Thermal zone temperature
|
||||
temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
|
||||
if (temp == -999999)
|
||||
return "ffSysctlGetInt(\"dev.cpu.0.temperature\" or \"hw.acpi.thermal.tz0.temperature\") failed";
|
||||
}
|
||||
}
|
||||
|
||||
// In tenth of degrees Kelvin
|
||||
*current = (double) temp / 10 - 273.15;
|
||||
@@ -94,11 +98,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (options->temp)
|
||||
{
|
||||
if (detectCpuTemp(&cpu->temperature) != NULL)
|
||||
detectThermalTemp(&cpu->temperature);
|
||||
}
|
||||
if (options->temp) detectCpuTemp(options, &cpu->temperature);
|
||||
|
||||
cpu->numaNodes = (uint16_t) ffSysctlGetInt("vm.ndomains", 0);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "common/properties.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/path.h"
|
||||
|
||||
#include <sys/sysinfo.h>
|
||||
#include <stdlib.h>
|
||||
@@ -13,6 +14,22 @@
|
||||
|
||||
#define FF_CPUINFO_PATH "/proc/cpuinfo"
|
||||
|
||||
#ifndef O_PATH
|
||||
#define O_PATH 0
|
||||
#endif
|
||||
|
||||
static double readTempFile(int dfd, const char* filename, FFstrbuf* buffer)
|
||||
{
|
||||
if (filename ? !ffReadFileBufferRelative(dfd, filename, buffer) : !ffReadFDBuffer(dfd, buffer))
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET); // millidegree Celsius
|
||||
if (value == FF_CPU_TEMP_UNSET)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
return value / 1000.;
|
||||
}
|
||||
|
||||
static double parseTZDir(int dfd, FFstrbuf* buffer)
|
||||
{
|
||||
if (!ffReadFileBufferRelative(dfd, "type", buffer))
|
||||
@@ -26,18 +43,12 @@ static double parseTZDir(int dfd, FFstrbuf* buffer)
|
||||
true
|
||||
) return FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (!ffReadFileBufferRelative(dfd, "temp", buffer))
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius
|
||||
if (value == FF_CPU_TEMP_UNSET)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
return value / 1000.;
|
||||
return readTempFile(dfd, "temp", buffer);
|
||||
}
|
||||
|
||||
static double parseHwmonDir(int dfd, FFstrbuf* buffer)
|
||||
{
|
||||
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
|
||||
if (!ffReadFileBufferRelative(dfd, "name", buffer))
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
@@ -53,25 +64,64 @@ static double parseHwmonDir(int dfd, FFstrbuf* buffer)
|
||||
true
|
||||
) return FF_CPU_TEMP_UNSET;
|
||||
|
||||
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
|
||||
if (!ffReadFileBufferRelative(dfd, "temp1_input", buffer))
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius
|
||||
if (value == FF_CPU_TEMP_UNSET)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
return value / 1000.;
|
||||
return readTempFile(dfd, "temp1_input", buffer);
|
||||
}
|
||||
|
||||
static double detectCPUTemp(void)
|
||||
static double detectCPUTemp(const FFCPUOptions* options)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
|
||||
if (options->tempSensor.length > 0)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int subfd = -1;
|
||||
const char* fileName = NULL;
|
||||
if (ffStrbufStartsWithS(&options->tempSensor, "hwmon") && ffCharIsDigit(options->tempSensor.chars[strlen("hwmon")]))
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int dfd = open("/sys/class/hwmon/", O_PATH | O_CLOEXEC);
|
||||
subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
|
||||
if (subfd >= 0)
|
||||
fileName = "temp1_input";
|
||||
else
|
||||
subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_CLOEXEC);
|
||||
}
|
||||
else if (ffStrbufStartsWithS(&options->tempSensor, "thermal_zone") && ffCharIsDigit(options->tempSensor.chars[strlen("thermal_zone")]))
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int dfd = open("/sys/class/thermal/", O_PATH | O_CLOEXEC);
|
||||
subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
|
||||
if (subfd >= 0)
|
||||
fileName = "temp";
|
||||
else
|
||||
subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_CLOEXEC);
|
||||
}
|
||||
else if (ffStrbufStartsWithS(&options->tempSensor, "cputemp.") && ffCharIsDigit(options->tempSensor.chars[strlen("cputemp.")]))
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int dfd = open("/sys/class/platform/", O_PATH | O_CLOEXEC);
|
||||
subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
|
||||
if (subfd >= 0)
|
||||
fileName = "temp1_input";
|
||||
else
|
||||
subfd = openat(dfd, options->tempSensor.chars, O_RDONLY | O_CLOEXEC);
|
||||
}
|
||||
else if (ffIsAbsolutePath(options->tempSensor.chars))
|
||||
{
|
||||
subfd = open(options->tempSensor.chars, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
|
||||
if (subfd >= 0)
|
||||
fileName = "temp1_input";
|
||||
else
|
||||
subfd = open(options->tempSensor.chars, O_RDONLY | O_CLOEXEC);
|
||||
}
|
||||
if (subfd < 0)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
return readTempFile(subfd, fileName, &buffer);
|
||||
}
|
||||
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/hwmon/");
|
||||
if(dirp)
|
||||
{
|
||||
int dfd = dirfd(dirp);
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
@@ -816,9 +866,9 @@ FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const c
|
||||
char* pend;
|
||||
unsigned long id = strtoul(p, &pend, 10);
|
||||
if (__builtin_expect(id > 64, false))
|
||||
high |= 1 << (id - 64);
|
||||
high |= 1UL << (id - 64);
|
||||
else
|
||||
low |= 1 << id;
|
||||
low |= 1UL << id;
|
||||
p = pend;
|
||||
}
|
||||
|
||||
@@ -902,7 +952,7 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options,
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
|
||||
cpu->temperature = options->temp ? detectCPUTemp(options) : FF_CPU_TEMP_UNSET;
|
||||
|
||||
#if __x86_64__ || __i386__
|
||||
return detectCPUX86(options, cpu);
|
||||
|
||||
@@ -16,7 +16,7 @@ static void freePropDict(prop_dictionary_t* pdict)
|
||||
prop_object_release(*pdict);
|
||||
}
|
||||
|
||||
static const char* detectCpuTemp(double* current)
|
||||
static const char* detectCpuTemp(const FFCPUOptions* options, double* current)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed";
|
||||
@@ -25,11 +25,21 @@ static const char* detectCpuTemp(double* current)
|
||||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
|
||||
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
||||
|
||||
prop_array_t array = prop_dictionary_get(root, "coretemp0");
|
||||
if (!array) array = prop_dictionary_get(root, "amdzentemp0");
|
||||
if (!array) array = prop_dictionary_get(root, "viac7temp0");
|
||||
if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
|
||||
if (!array) return "No temp data found in root dictionary";
|
||||
prop_array_t array;
|
||||
|
||||
if (options->tempSensor.length > 0)
|
||||
{
|
||||
array = prop_dictionary_get(root, options->tempSensor.chars);
|
||||
if (!array) return "No temp data found in specified sensor";
|
||||
}
|
||||
else
|
||||
{
|
||||
array = prop_dictionary_get(root, "coretemp0");
|
||||
if (!array) array = prop_dictionary_get(root, "amdzentemp0");
|
||||
if (!array) array = prop_dictionary_get(root, "viac7temp0");
|
||||
if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
|
||||
if (!array) return "No temp data found in root dictionary";
|
||||
}
|
||||
|
||||
if (prop_array_count(array) != 2)
|
||||
return "Unexpected `xtemp0` data";
|
||||
@@ -73,7 +83,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (options->temp) detectCpuTemp(&cpu->temperature);
|
||||
if (options->temp) detectCpuTemp(options, &cpu->temperature);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/sensors.h>
|
||||
|
||||
static const char* detectCPUTemp(FFCPUResult* cpu)
|
||||
static const char* detectCPUTemp(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
int mib[5] = {CTL_HW, HW_SENSORS, 0, SENSOR_TEMP, 0};
|
||||
|
||||
@@ -23,8 +23,16 @@ static const char* detectCPUTemp(FFCPUResult* cpu)
|
||||
return "sysctl(sensordev) failed";
|
||||
}
|
||||
|
||||
if (!ffStrStartsWith(sensordev.xname, "cpu"))
|
||||
continue;
|
||||
if (options->tempSensor.length > 0)
|
||||
{
|
||||
if (!ffStrbufEqualS(&options->tempSensor, sensordev.xname))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ffStrStartsWith(sensordev.xname, "cpu"))
|
||||
continue;
|
||||
}
|
||||
|
||||
for (mib[4] = 0; mib[4] < sensordev.maxnumt[SENSOR_TEMP]; mib[4]++)
|
||||
{
|
||||
@@ -62,7 +70,7 @@ const char *ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
if (cpuspeed > cpu->frequencyBase) cpu->frequencyBase = cpuspeed;
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
if (options->temp) detectCPUTemp(cpu);
|
||||
if (options->temp) detectCPUTemp(options, cpu);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,15 @@
|
||||
#include "util/stringUtils.h"
|
||||
#include <kstat.h>
|
||||
|
||||
static const char* detectCPUTempByKstat(kstat_ctl_t* kc, FFCPUResult* cpu)
|
||||
static const char* detectCPUTempByKstat(const FFCPUOptions* options, kstat_ctl_t* kc, FFCPUResult* cpu)
|
||||
{
|
||||
const char* possibleModules[] = {"temperature", "cpu_temp", "acpi_thermal", NULL};
|
||||
|
||||
if (options->tempSensor.length > 0) {
|
||||
possibleModules[0] = options->tempSensor.chars;
|
||||
possibleModules[1] = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; possibleModules[i] != NULL; i++) {
|
||||
kstat_t* ks = kstat_lookup(kc, possibleModules[i], -1, NULL);
|
||||
if (ks && kstat_read(kc, ks, NULL) >= 0) {
|
||||
@@ -141,7 +146,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
if (options->temp)
|
||||
{
|
||||
if (detectCPUTempByKstat(kc, cpu) != NULL)
|
||||
if (detectCPUTempByKstat(options, kc, cpu) != NULL)
|
||||
detectCPUTempByIpmiTool(cpu);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ static inline void ffPerfCloseQueryHandle(HANDLE* phQuery)
|
||||
}
|
||||
}
|
||||
|
||||
const char* detectThermalTemp(double* result)
|
||||
const char* detectThermalTemp(const FFCPUOptions* options, double* result)
|
||||
{
|
||||
struct FFPerfQuerySpec
|
||||
{
|
||||
@@ -35,6 +35,14 @@ const char* detectThermalTemp(double* result)
|
||||
.Name = L"\\_TZ.CPUZ", // The standard(?) instance name for CPU temperature in the thermal provider
|
||||
};
|
||||
|
||||
if (options->tempSensor.length > 0)
|
||||
{
|
||||
int written = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, options->tempSensor.chars, (int) options->tempSensor.length, querySpec.Name, (int)(ARRAY_SIZE(querySpec.Name) - 1));
|
||||
if (written == 0)
|
||||
return "Invalid temp sensor string";
|
||||
querySpec.Name[written] = L'\0';
|
||||
}
|
||||
|
||||
DWORD dataSize = 0;
|
||||
if (PerfEnumerateCounterSetInstances(NULL, &querySpec.Identifier.CounterSetGuid, NULL, 0, &dataSize) != ERROR_NOT_ENOUGH_MEMORY)
|
||||
return "PerfEnumerateCounterSetInstances() failed";
|
||||
@@ -62,6 +70,9 @@ const char* detectThermalTemp(double* result)
|
||||
|
||||
if (dataSize == 0)
|
||||
{
|
||||
if (options->tempSensor.length > 0)
|
||||
return "Unable to find CPU sensor";
|
||||
|
||||
const wchar_t* instanceName = (const wchar_t*)((BYTE*)pHead + sizeof(*pHead));
|
||||
wcscpy(querySpec.Name, instanceName); // Use the first instance name if the specific one is not found
|
||||
}
|
||||
@@ -301,7 +312,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
detectMaxSpeedBySmbios(cpu);
|
||||
|
||||
if(options->temp)
|
||||
detectThermalTemp(&cpu->temperature);
|
||||
detectThermalTemp(options, &cpu->temperature);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result)
|
||||
if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed";
|
||||
|
||||
// macOS provides the global system cache line size
|
||||
uint32_t lineSize = (uint32_t) ffSysctlGetInt("hw.cachelinesize", 0);
|
||||
uint32_t lineSize = (uint32_t) ffSysctlGetInt64("hw.cachelinesize", 0);
|
||||
|
||||
char sysctlKey[128] = "hw.perflevelN.";
|
||||
char* pNum = sysctlKey + strlen("hw.perflevel");
|
||||
|
||||
@@ -239,6 +239,11 @@ enum kde_output_device_v2_capability {
|
||||
* @since 17
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_SHARPNESS = 0x1000,
|
||||
/**
|
||||
* if this outputdevice supports custom modes
|
||||
* @since 18
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_CUSTOM_MODES = 0x2000,
|
||||
};
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
@@ -280,6 +285,10 @@ enum kde_output_device_v2_capability {
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_SHARPNESS_SINCE_VERSION 17
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_CUSTOM_MODES_SINCE_VERSION 18
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM
|
||||
@@ -794,6 +803,23 @@ struct kde_output_device_v2_listener {
|
||||
void (*sharpness)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t sharpness);
|
||||
/**
|
||||
* output priority
|
||||
*
|
||||
* Describes the position of the output in the output order list,
|
||||
* with lower values being earlier in the list. There's no specific
|
||||
* value the list has to start at, this value is only used in
|
||||
* sorting outputs.
|
||||
*
|
||||
* Note that the output order protocol is not sufficient for this,
|
||||
* as an output may not be in the output order if it's disabled or
|
||||
* mirroring another screen.
|
||||
* @param priority priority
|
||||
* @since 18
|
||||
*/
|
||||
void (*priority)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t priority);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -943,6 +969,10 @@ kde_output_device_v2_add_listener(struct kde_output_device_v2 *kde_output_device
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_SHARPNESS_SINCE_VERSION 17
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_PRIORITY_SINCE_VERSION 18
|
||||
|
||||
|
||||
/** @ingroup iface_kde_output_device_v2 */
|
||||
@@ -972,6 +1002,18 @@ kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2);
|
||||
}
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
* mode flags
|
||||
*/
|
||||
enum kde_output_device_mode_v2_flags {
|
||||
KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_CUSTOM = 0x1,
|
||||
KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_REDUCED_BLANKING = 0x2,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
* @struct kde_output_device_mode_v2_listener
|
||||
@@ -1017,6 +1059,15 @@ struct kde_output_device_mode_v2_listener {
|
||||
*/
|
||||
void (*removed)(void *data,
|
||||
struct kde_output_device_mode_v2 *kde_output_device_mode_v2);
|
||||
/**
|
||||
* mode flags
|
||||
*
|
||||
* This event describes the mode's flags.
|
||||
* @since 19
|
||||
*/
|
||||
void (*flags)(void *data,
|
||||
struct kde_output_device_mode_v2 *kde_output_device_mode_v2,
|
||||
uint32_t flags);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1046,6 +1097,10 @@ kde_output_device_mode_v2_add_listener(struct kde_output_device_mode_v2 *kde_out
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_FLAGS_SINCE_VERSION 19
|
||||
|
||||
|
||||
/** @ingroup iface_kde_output_device_mode_v2 */
|
||||
|
||||
@@ -67,12 +67,13 @@ static const struct wl_message kde_output_device_v2_events[] = {
|
||||
{ "automatic_max_bits_per_color_limit", "15u", kde_output_device_v2_types + 0 },
|
||||
{ "edr_policy", "16u", kde_output_device_v2_types + 0 },
|
||||
{ "sharpness", "17u", kde_output_device_v2_types + 0 },
|
||||
{ "priority", "18u", kde_output_device_v2_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface kde_output_device_v2_interface = {
|
||||
"kde_output_device_v2", 17,
|
||||
"kde_output_device_v2", 19,
|
||||
0, NULL,
|
||||
34, kde_output_device_v2_events,
|
||||
35, kde_output_device_v2_events,
|
||||
};
|
||||
|
||||
static const struct wl_message kde_output_device_mode_v2_events[] = {
|
||||
@@ -80,12 +81,13 @@ static const struct wl_message kde_output_device_mode_v2_events[] = {
|
||||
{ "refresh", "i", kde_output_device_v2_types + 0 },
|
||||
{ "preferred", "", kde_output_device_v2_types + 0 },
|
||||
{ "removed", "", kde_output_device_v2_types + 0 },
|
||||
{ "flags", "19u", kde_output_device_v2_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface kde_output_device_mode_v2_interface = {
|
||||
"kde_output_device_mode_v2", 1,
|
||||
"kde_output_device_mode_v2", 19,
|
||||
0, NULL,
|
||||
4, kde_output_device_mode_v2_events,
|
||||
5, kde_output_device_mode_v2_events,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -178,6 +178,7 @@ static struct kde_output_device_v2_listener outputListener = {
|
||||
.automatic_max_bits_per_color_limit = (void*) stubListener,
|
||||
.edr_policy = (void*) stubListener,
|
||||
.sharpness = (void*) stubListener,
|
||||
.priority = (void*) stubListener,
|
||||
};
|
||||
|
||||
const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
|
||||
@@ -605,7 +605,7 @@ static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
|
||||
|
||||
if (ffStrbufStartsWithS(&buffer, "pci:"))
|
||||
detectPci(options, gpus, &buffer, &drmDir, entry->d_name);
|
||||
else if (ffStrbufStartsWithS(&buffer, "of:"))
|
||||
else if (ffStrbufStartsWithS(&buffer, "of:")) // Open Firmware
|
||||
detectOf(gpus, &buffer, &drmDir, entry->d_name);
|
||||
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
|
||||
@@ -45,7 +45,8 @@ const char* getOthersByIokit(FFHostResult* host)
|
||||
|
||||
const char* ffDetectHost(FFHostResult* host)
|
||||
{
|
||||
const char* error = ffSysctlGetString("hw.model", &host->family);
|
||||
const char* error = ffSysctlGetString("hw.product", &host->family);
|
||||
if (error) error = ffSysctlGetString("hw.model", &host->family);
|
||||
if (error) return error;
|
||||
|
||||
ffStrbufSetStatic(&host->name, ffHostGetMacProductNameWithHwModel(&host->family));
|
||||
|
||||
@@ -8,24 +8,25 @@
|
||||
const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
{
|
||||
size_t length = sizeof(ram->bytesTotal);
|
||||
if (sysctl((int[]){ CTL_HW, HW_MEMSIZE }, 2, &ram->bytesTotal, &length, NULL, 0))
|
||||
if (sysctl((int[]){ CTL_HW, HW_MEMSIZE }, 2, &ram->bytesTotal, &length, NULL, 0) != 0)
|
||||
return "Failed to read hw.memsize";
|
||||
uint64_t usableMemory = 0;
|
||||
length = sizeof(usableMemory);
|
||||
if (sysctlbyname("hw.memsize_usable", &usableMemory, &length, NULL, 0) != 0)
|
||||
usableMemory = ram->bytesTotal;
|
||||
|
||||
mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
|
||||
vm_statistics64_data_t vmstat;
|
||||
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
|
||||
return "Failed to read host_statistics64";
|
||||
|
||||
// https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56
|
||||
ram->bytesUsed = ((uint64_t)
|
||||
+ vmstat.active_count
|
||||
+ vmstat.inactive_count
|
||||
+ vmstat.speculative_count
|
||||
+ vmstat.wire_count
|
||||
+ vmstat.compressor_page_count
|
||||
- vmstat.purgeable_count
|
||||
- vmstat.external_page_count
|
||||
) * instance.state.platform.sysinfo.pageSize;
|
||||
uint64_t pageSize = instance.state.platform.sysinfo.pageSize;
|
||||
uint64_t appMemory = vmstat.internal_page_count * pageSize;
|
||||
uint64_t wiredMemory = vmstat.wire_count * pageSize;
|
||||
uint64_t compressed = vmstat.compressor_page_count * pageSize;
|
||||
uint64_t reserved = ram->bytesTotal - usableMemory;
|
||||
|
||||
ram->bytesUsed = appMemory + wiredMemory + compressed + reserved;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2,35 +2,67 @@
|
||||
#include "common/processing.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/path.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <handleapi.h>
|
||||
#include <fileapi.h>
|
||||
#include <windows.h>
|
||||
#include "util/windows/nt.h"
|
||||
#include <ntstatus.h>
|
||||
|
||||
static uint32_t getNumElements(const char* searchPath /* including `\*` suffix */, DWORD type, const char* ignore)
|
||||
static uint32_t getNumElements(const char* searchPath, DWORD type, const wchar_t* ignore)
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
bool flag = ignore == NULL;
|
||||
WIN32_FIND_DATAA wfd;
|
||||
HANDLE hFind = FindFirstFileA(searchPath, &wfd);
|
||||
FF_AUTO_CLOSE_FD HANDLE dfd = CreateFileA(searchPath, FILE_LIST_DIRECTORY | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (dfd == INVALID_HANDLE_VALUE) return 0;
|
||||
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do // Managed to locate and create an handle to that folder.
|
||||
bool flag = ignore == NULL;
|
||||
uint32_t counter = 0;
|
||||
uint8_t buffer[64 * 1024] __attribute__((aligned(8))); // Required for WoA
|
||||
BOOLEAN firstScan = TRUE;
|
||||
|
||||
size_t ignoreLen = ignore ? wcslen(ignore) : 0;
|
||||
|
||||
while (true) {
|
||||
IO_STATUS_BLOCK ioStatus = {};
|
||||
NTSTATUS status = NtQueryDirectoryFile(
|
||||
dfd,
|
||||
NULL, NULL, NULL,
|
||||
&ioStatus,
|
||||
buffer, ARRAY_SIZE(buffer),
|
||||
FileDirectoryInformation,
|
||||
FALSE,
|
||||
NULL,
|
||||
firstScan
|
||||
);
|
||||
firstScan = FALSE;
|
||||
|
||||
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) break;
|
||||
|
||||
for (FILE_DIRECTORY_INFORMATION* entry = (FILE_DIRECTORY_INFORMATION*) buffer;
|
||||
;
|
||||
entry = (FILE_DIRECTORY_INFORMATION*) ((uint8_t*) entry + entry->NextEntryOffset))
|
||||
{
|
||||
if(!(wfd.dwFileAttributes & type)) continue;
|
||||
if(!flag && ffStrEqualsIgnCase(ignore, wfd.cFileName))
|
||||
if (!(entry->FileAttributes & type)) continue;
|
||||
|
||||
if (!flag &&
|
||||
ignoreLen == entry->FileNameLength / sizeof(*entry->FileName) &&
|
||||
_wcsnicmp(entry->FileName, ignore, ignoreLen) == 0)
|
||||
{
|
||||
flag = true;
|
||||
continue;
|
||||
}
|
||||
counter++;
|
||||
} while (FindNextFileA(hFind, &wfd));
|
||||
FindClose(hFind);
|
||||
|
||||
if(type == FILE_ATTRIBUTE_DIRECTORY && counter >= 2)
|
||||
counter -= 2; // accounting for . and ..
|
||||
counter++;
|
||||
|
||||
if (entry->NextEntryOffset == 0) break;
|
||||
}
|
||||
|
||||
if (status == STATUS_SUCCESS) break; // No next page
|
||||
}
|
||||
|
||||
if(type == FILE_ATTRIBUTE_DIRECTORY && counter >= 2)
|
||||
counter -= 2; // accounting for . and ..
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@@ -65,8 +97,8 @@ static void detectScoop(FFPackagesResult* result)
|
||||
ffStrbufSet(&scoopPath, &instance.state.platform.homeDir);
|
||||
ffStrbufAppendS(&scoopPath, "/scoop");
|
||||
}
|
||||
ffStrbufAppendS(&scoopPath, "/apps/*");
|
||||
result->scoopUser = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, "scoop");
|
||||
ffStrbufAppendS(&scoopPath, "/apps/");
|
||||
result->scoopUser = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, L"scoop");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -78,8 +110,8 @@ static void detectScoop(FFPackagesResult* result)
|
||||
ffStrbufSetS(&scoopPath, getenv("ProgramData"));
|
||||
ffStrbufAppendS(&scoopPath, "/scoop");
|
||||
}
|
||||
ffStrbufAppendS(&scoopPath, "/apps/*");
|
||||
result->scoopGlobal = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, "scoop");
|
||||
ffStrbufAppendS(&scoopPath, "/apps/");
|
||||
result->scoopGlobal = getNumElements(scoopPath.chars, FILE_ATTRIBUTE_DIRECTORY, L"scoop");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,8 +123,8 @@ static void detectChoco(FF_MAYBE_UNUSED FFPackagesResult* result)
|
||||
|
||||
char chocoPath[MAX_PATH + 3];
|
||||
char* pend = ffStrCopy(chocoPath, chocoInstall, ARRAY_SIZE(chocoPath));
|
||||
ffStrCopy(pend, "/lib/*", ARRAY_SIZE(chocoPath) - (size_t) (pend - chocoPath));
|
||||
result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY, "choco");
|
||||
ffStrCopy(pend, "/lib/", ARRAY_SIZE(chocoPath) - (size_t) (pend - chocoPath));
|
||||
result->choco = getNumElements(chocoPath, FILE_ATTRIBUTE_DIRECTORY, L"choco");
|
||||
}
|
||||
|
||||
static void detectPacman(FFPackagesResult* result)
|
||||
@@ -104,7 +136,7 @@ static void detectPacman(FFPackagesResult* result)
|
||||
// MSYS2
|
||||
char pacmanPath[MAX_PATH + 3];
|
||||
char* pend = ffStrCopy(pacmanPath, msystemPrefix, ARRAY_SIZE(pacmanPath));
|
||||
ffStrCopy(pend, "/../var/lib/pacman/local/*", ARRAY_SIZE(pacmanPath) - (size_t) (pend - pacmanPath));
|
||||
ffStrCopy(pend, "/../var/lib/pacman/local/", ARRAY_SIZE(pacmanPath) - (size_t) (pend - pacmanPath));
|
||||
result->pacman = getNumElements(pacmanPath, FILE_ATTRIBUTE_DIRECTORY, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#include <winternl.h>
|
||||
#include <ntstatus.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
|
||||
const char* ffDetectSwap(FFlist* result)
|
||||
const char* detectByNqsi(FFlist* result)
|
||||
{
|
||||
uint8_t buffer[4096];
|
||||
ULONG size = sizeof(buffer);
|
||||
@@ -26,6 +27,27 @@ const char* ffDetectSwap(FFlist* result)
|
||||
if (current->NextEntryOffset == 0)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* detectByKgpi(FFlist* result)
|
||||
{
|
||||
PERFORMANCE_INFORMATION pi = {};
|
||||
if (!K32GetPerformanceInfo(&pi, sizeof(pi)))
|
||||
return "K32GetPerformanceInfo(&pi, sizeof(pi)) failed";
|
||||
FFSwapResult* swap = ffListAdd(result);
|
||||
ffStrbufInitS(&swap->name, "Page File");
|
||||
swap->bytesTotal = (uint64_t) (pi.CommitLimit > pi.PhysicalTotal ? pi.CommitLimit - pi.PhysicalTotal : 0) * pi.PageSize;
|
||||
swap->bytesUsed = (uint64_t) (pi.CommitTotal > pi.PhysicalTotal ? pi.CommitTotal - pi.PhysicalTotal : 0) * pi.PageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectSwap(FFlist* result)
|
||||
{
|
||||
const char* err = detectByNqsi(result);
|
||||
if (err == NULL)
|
||||
return NULL;
|
||||
|
||||
return detectByKgpi(result);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
################
|
||||
########################
|
||||
##########-- --##########
|
||||
#######* ****** *#######
|
||||
###### --*######--- ######
|
||||
##### --- *#### #####
|
||||
##### *-- #*#*#* * #### #####
|
||||
#####* ##- ##*-#* ### ### *#####
|
||||
##### ###* -##*#* *# *# *### #####
|
||||
##### ###* -*##*-*## *#* ### #####
|
||||
##### #### - --#### - ##* ### #####
|
||||
##### *####* * - ###- ##* #####
|
||||
#####* #######- *###- ### *#####
|
||||
#####* ***#####****--- ### *#####
|
||||
###### ----------- - ### ######
|
||||
###### ----- ### ######
|
||||
####### #######
|
||||
##########*----*##########
|
||||
######################
|
||||
##############
|
||||
@@ -1,13 +0,0 @@
|
||||
.':ldkOOOOkxo:,.
|
||||
.:d0KKXXXXXXXXXXKkl,
|
||||
.;xOOO0000KKKKXXXXXXX0l.
|
||||
.cxxxkkkkOOO0000KKKKXXXXx'
|
||||
;ool;,,,,;coxkOOOO0000KKKd.
|
||||
.clc'.........:oxkkkkOOOO0O,
|
||||
.ccc:ccclc:,....,:oddxxdxkO;
|
||||
cllllccccccc;'........'lxx.
|
||||
'ooooolllllccc:;,''',,coo,
|
||||
,ddddooooollllllccccccl'
|
||||
cxxxdddddooooollllc;
|
||||
,dxxxxxddddddol.
|
||||
.';::,.
|
||||
+1
-7
@@ -2157,7 +2157,7 @@ static const FFlogo G[] = {
|
||||
// GXDE
|
||||
{
|
||||
.names = {"GXDE"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_DEEPIN,
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_GXDE,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
},
|
||||
@@ -3455,12 +3455,6 @@ static const FFlogo O[] = {
|
||||
FF_COLOR_FG_LIGHT_BLACK,
|
||||
}
|
||||
},
|
||||
// Opak
|
||||
{
|
||||
.names = {"Opak"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_OPAK,
|
||||
.colors = {}, // #1070
|
||||
},
|
||||
// OpenKylin
|
||||
{
|
||||
.names = {"openkylin", "open-kylin"},
|
||||
|
||||
@@ -134,6 +134,12 @@ void ffParseCPUJsonObject(FFCPUOptions* options, yyjson_val* module)
|
||||
if (ffTempsParseJsonObject(key, val, &options->temp, &options->tempConfig))
|
||||
continue;
|
||||
|
||||
if (unsafe_yyjson_equals_str(key, "tempSensor"))
|
||||
{
|
||||
ffStrbufSetS(&options->tempSensor, unsafe_yyjson_get_str(val));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unsafe_yyjson_equals_str(key, "freqNdigits"))
|
||||
{
|
||||
ffPrintError(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "modules.CPU.freqNdigits has been moved to display.freq.ndigits");
|
||||
@@ -234,6 +240,7 @@ bool ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
void ffInitCPUOptions(FFCPUOptions* options)
|
||||
{
|
||||
ffOptionInitModuleArg(&options->moduleArgs, "");
|
||||
ffStrbufInit(&options->tempSensor);
|
||||
options->temp = false;
|
||||
options->tempConfig = (FFColorRangeConfig) { 60, 80 };
|
||||
options->showPeCoreCount = false;
|
||||
@@ -242,6 +249,7 @@ void ffInitCPUOptions(FFCPUOptions* options)
|
||||
void ffDestroyCPUOptions(FFCPUOptions* options)
|
||||
{
|
||||
ffOptionDestroyModuleArg(&options->moduleArgs);
|
||||
ffStrbufDestroy(&options->tempSensor);
|
||||
}
|
||||
|
||||
FFModuleBaseInfo ffCPUModuleInfo = {
|
||||
|
||||
@@ -6,6 +6,7 @@ typedef struct FFCPUOptions
|
||||
{
|
||||
FFModuleArgs moduleArgs;
|
||||
|
||||
FFstrbuf tempSensor;
|
||||
bool temp;
|
||||
FFColorRangeConfig tempConfig;
|
||||
bool showPeCoreCount;
|
||||
|
||||
@@ -277,15 +277,32 @@ static bool detectTemp(io_connect_t conn, const char* sensor, double* sum)
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* ffDetectSmcTemps(enum FFTempType type, double* result)
|
||||
static io_connect_t conn;
|
||||
|
||||
const char* ffDetectSmcSpecificTemp(const char* sensor, double* result)
|
||||
{
|
||||
static io_connect_t conn;
|
||||
if (!conn)
|
||||
{
|
||||
if (smcOpen(&conn) != NULL)
|
||||
conn = (io_connect_t) -1;
|
||||
}
|
||||
else if (conn == (io_connect_t) -1)
|
||||
if (conn == (io_connect_t) -1)
|
||||
return "Could not open SMC connection";
|
||||
|
||||
if (!detectTemp(conn, sensor, result))
|
||||
return "Could not read SMC temperature";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectSmcTemps(enum FFTempType type, double* result)
|
||||
{
|
||||
if (!conn)
|
||||
{
|
||||
if (smcOpen(&conn) != NULL)
|
||||
conn = (io_connect_t) -1;
|
||||
}
|
||||
if (conn == (io_connect_t) -1)
|
||||
return "Could not open SMC connection";
|
||||
|
||||
uint32_t count = 0;
|
||||
|
||||
@@ -30,4 +30,5 @@ enum FFTempType
|
||||
FF_TEMP_MEMORY,
|
||||
};
|
||||
|
||||
const char* ffDetectSmcSpecificTemp(const char* sensor, double* result);
|
||||
const char* ffDetectSmcTemps(enum FFTempType type, double* result);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
static void getExePath(FFPlatform* platform)
|
||||
{
|
||||
char exePath[PATH_MAX + 1];
|
||||
char exePath[PATH_MAX];
|
||||
#if defined(__linux__) || defined (__GNU__)
|
||||
ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
|
||||
if (exePathLen >= 0)
|
||||
@@ -58,7 +58,7 @@ static void getExePath(FFPlatform* platform)
|
||||
|
||||
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
|
||||
if (info.type == B_APP_IMAGE) {
|
||||
exePathLen = strlcpy(exePath, info.name, PATH_MAX);
|
||||
exePathLen = strlcpy(exePath, info.name, sizeof(exePath));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ static void getExePath(FFPlatform* platform)
|
||||
{
|
||||
wchar_t exePathW[MAX_PATH];
|
||||
DWORD exePathWLen = GetModuleFileNameW(NULL, exePathW, MAX_PATH);
|
||||
if (exePathWLen == 0 && exePathWLen >= MAX_PATH) return;
|
||||
if (exePathWLen == 0 || exePathWLen >= MAX_PATH) return;
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(exePathW, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (hPath != INVALID_HANDLE_VALUE)
|
||||
@@ -164,8 +164,12 @@ static void getHostName(FFPlatform* platform)
|
||||
static void getUserShell(FFPlatform* platform)
|
||||
{
|
||||
// Works in MSYS2
|
||||
ffStrbufAppendS(&platform->userShell, getenv("SHELL"));
|
||||
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
|
||||
const char* userShell = getenv("SHELL");
|
||||
if (userShell)
|
||||
{
|
||||
ffStrbufAppendS(&platform->userShell, userShell);
|
||||
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
|
||||
}
|
||||
}
|
||||
|
||||
static const char* detectWine(void)
|
||||
|
||||
@@ -232,3 +232,19 @@ typedef struct _D3DKMT_NODEMETADATA
|
||||
static_assert(sizeof(D3DKMT_NODEMETADATA) == 0x4E, "D3DKMT_NODEMETADATA structure size mismatch");
|
||||
|
||||
#endif
|
||||
|
||||
NTSYSCALLAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtQueryDirectoryFile(
|
||||
IN HANDLE FileHandle,
|
||||
IN HANDLE Event OPTIONAL,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
OUT PVOID FileInformation,
|
||||
IN ULONG Length,
|
||||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||||
IN BOOLEAN ReturnSingleEntry,
|
||||
IN PUNICODE_STRING FileName OPTIONAL,
|
||||
IN BOOLEAN RestartScan);
|
||||
|
||||
@@ -11,7 +11,7 @@ void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
|
||||
}
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL);
|
||||
if (size_needed < 0)
|
||||
if (size_needed <= 0)
|
||||
{
|
||||
ffStrbufSetF(result, "WCTMB failed: %u", (unsigned) GetLastError());
|
||||
return;
|
||||
@@ -21,3 +21,18 @@ void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
|
||||
result->length = (uint32_t)size_needed;
|
||||
result->chars[size_needed] = '\0';
|
||||
}
|
||||
|
||||
void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
|
||||
{
|
||||
if(!length)
|
||||
return;
|
||||
|
||||
int size_needed = WideCharToMultiByte(CP_UTF8, 0, source, (int)length, NULL, 0, NULL, NULL);
|
||||
if (size_needed <= 0)
|
||||
return;
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t)size_needed);
|
||||
WideCharToMultiByte(CP_UTF8, 0, source, (int)length, result->chars + result->length, size_needed, NULL, NULL);
|
||||
result->length += (uint32_t)size_needed;
|
||||
result->chars[result->length] = '\0';
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <wchar.h>
|
||||
|
||||
void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source);
|
||||
void ffStrbufAppendNWS(FFstrbuf* result, uint32_t length, const wchar_t* source);
|
||||
|
||||
static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source)
|
||||
{
|
||||
@@ -11,6 +12,12 @@ static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source)
|
||||
return ffStrbufSetNWS(result, (uint32_t)wcslen(source), source);
|
||||
}
|
||||
|
||||
static inline void ffStrbufAppendWS(FFstrbuf* result, const wchar_t* source)
|
||||
{
|
||||
if (!source) return;
|
||||
return ffStrbufAppendNWS(result, (uint32_t)wcslen(source), source);
|
||||
}
|
||||
|
||||
static inline void ffStrbufInitNWS(FFstrbuf* result, uint32_t length, const wchar_t* source)
|
||||
{
|
||||
ffStrbufInit(result);
|
||||
|
||||
Reference in New Issue
Block a user