mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b40a81e22 | |||
| 8be64714ba | |||
| fe5d739cba | |||
| dba0672a11 | |||
| 3ed6acf3ca | |||
| 8c74c54bb0 | |||
| 818473102c | |||
| f1cc4a7805 | |||
| c574af97a4 | |||
| 74ae84e719 | |||
| 98738b6920 | |||
| 2e5769def2 | |||
| 18a6929662 | |||
| 0e61d1134d | |||
| 4abb183735 | |||
| d5b56be4ff | |||
| 1854953d8c | |||
| 2406015c81 | |||
| ec7f14ab96 | |||
| d94cdf4424 | |||
| 40e57b7698 | |||
| 974c658fff | |||
| ad0ddfd7f1 | |||
| 1da8367f55 | |||
| bdbc885811 | |||
| 86e5a5997b | |||
| 9832a0e45b | |||
| addf674621 | |||
| 863c5583ef | |||
| 45cbc6de83 | |||
| e68f766b4d | |||
| 29d7a1acac | |||
| 8d59d14b80 | |||
| ed1883909a | |||
| 049701a8a9 | |||
| 13b7bc89eb | |||
| 92fe44183d | |||
| 8ebc980c17 | |||
| dbeb338bda | |||
| 65ff11a8d0 | |||
| 7a73211484 | |||
| ca049997b1 | |||
| a9f021ccb9 | |||
| 55249c2294 | |||
| c13da56959 | |||
| 665c7cd5d3 |
@@ -552,7 +552,7 @@ jobs:
|
||||
architecture: x86-64
|
||||
cpu_count: 4
|
||||
shell: bash
|
||||
version: '14.2'
|
||||
version: '14.3'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
|
||||
+31
-1
@@ -1,3 +1,33 @@
|
||||
# 2.47.0
|
||||
|
||||
Features:
|
||||
* Various improvements for Solaris / OpenIndiana support
|
||||
* Support BIOS (UEFI or legacy) type detection (BIOS)
|
||||
* Support physical disk detection (PhysicalDisk)
|
||||
* Remove leading `-` from login shells (Shell)
|
||||
* Improve GPU detection performance (GPU)
|
||||
* Drop `libpciaccess` dependency
|
||||
* Use native API to detect sound devices (Sound)
|
||||
* Drop `PulseAudio` dependency
|
||||
* Improve DietPi OS and Raspberry Pi OS detection (#1816, OS, Linux)
|
||||
* Force reporting version 26 on macOS Tahoe (OS, macOS)
|
||||
* Append version string to Ubuntu variants (OS, Linux)
|
||||
* Improve performance of media detection for macOS 15.4+ (Media, macOS)
|
||||
* Increase `PROC_FILE_BUFFSIZ` to avoid possible short reads (Linux)
|
||||
* Fix potential bugs in `DiskIO`, `NetIO` and `CPUUsage` modules
|
||||
* Improve accuracy of CPU usage calculations by including interrupt and softirq times (CPUUsage, Linux / *BSD)
|
||||
* Ignore `init` and `systemd` processes when detecting terminals (Terminal, Linux)
|
||||
* Improve accuracy of CPU usage detection on Windows 10+ with perflib, which matches values reported by Task Manager (CPUUsage, Windows)
|
||||
|
||||
Bugfixes:
|
||||
* Fix `pci.ids` file location (#1819, GPU, OpenBSD)
|
||||
* Fix compiling on FreeBSD when `libdrm` support is disabled (#1820, GPU, FreeBSD)
|
||||
|
||||
Logos:
|
||||
* Improve visibility on white-background terminals for some logos by replacing white with the default foreground color
|
||||
* According to Wikipedia, the default foreground color is implementation-defined. It's usually black for white themes and white for dark themes. However, some terminals, notably Konsole with the default theme, use a different color, which may cause issues with some logos.
|
||||
* Add Xubuntu
|
||||
|
||||
# 2.46.0
|
||||
|
||||
Features:
|
||||
@@ -12,7 +42,7 @@ Features:
|
||||
* Use `board-id` as board name if available (Board, macOS)
|
||||
* Intel only
|
||||
* Support shared VRAM usage detection for AMD GPUs (GPU, Linux)
|
||||
* Use `perflib.h` instead of `pdh.h` for CPU temperature querying to get rid of pdh.dll (#1787, CPU, Windows)
|
||||
* Use `perflib.h` instead of `pdh.h` for CPU temperature querying to get rid of `pdh.dll` dependency (#1787, CPU, Windows)
|
||||
* Support GPU info detection for old ATI radeon driver (#1810, GPU, Linux)
|
||||
* Add macOS 26 Tahoe support (macOS)
|
||||
* Report macOS 26 code name (OS)
|
||||
|
||||
+6
-10
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.46.0
|
||||
VERSION 2.47.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -76,13 +76,13 @@ cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD O
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly OR Haiku" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD" OFF)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||
@@ -326,11 +326,6 @@ endif()
|
||||
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
|
||||
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
|
||||
|
||||
if(APPLE)
|
||||
# See src/detection/media/media_apple.m
|
||||
fastfetch_load_text(src/data/nowPlaying.scptd DATATEXT_NOWPLAYING)
|
||||
endif()
|
||||
|
||||
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
|
||||
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
|
||||
if(APPLE)
|
||||
@@ -1062,7 +1057,7 @@ elseif(SunOS)
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/disk/disk_sunos.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
||||
src/detection/physicaldisk/physicaldisk_sunos.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_sunos.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
@@ -1102,7 +1097,7 @@ elseif(SunOS)
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_linux.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
src/detection/sound/sound_linux.c
|
||||
src/detection/sound/sound_sunos.c
|
||||
src/detection/swap/swap_sunos.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
@@ -1637,6 +1632,7 @@ elseif(SunOS)
|
||||
PRIVATE "proc"
|
||||
PRIVATE "zfs"
|
||||
PRIVATE "nvpair"
|
||||
PRIVATE "devinfo"
|
||||
)
|
||||
elseif(ANDROID)
|
||||
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
|
||||
@@ -69,13 +69,12 @@ If fastfetch is not packaged for your distribution or an outdated version is pac
|
||||
|
||||
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
|
||||
|
||||
### FreeBSD
|
||||
### BSD systems
|
||||
|
||||
* `pkg install fastfetch`
|
||||
|
||||
### NetBSD
|
||||
|
||||
* `pkgin in fastfetch`
|
||||
* FreeBSD: `pkg install fastfetch`
|
||||
* NetBSD: `pkgin in fastfetch`
|
||||
* OpenBSD: `pkg_add fastfetch` (Snapshots only)
|
||||
* DragonFly BSD: `pkg install fastfetch` (Snapshots only)
|
||||
|
||||
### Android (Termux)
|
||||
|
||||
|
||||
Vendored
+6
@@ -1,3 +1,9 @@
|
||||
fastfetch (2.46.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.46.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 20 Jun 2025 15:01:21 +0800
|
||||
|
||||
fastfetch (2.45.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.45.0
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.45.0_source.buildinfo universe/utils optional
|
||||
fastfetch_2.46.0_source.buildinfo universe/utils optional
|
||||
|
||||
+1
-2
@@ -19,8 +19,7 @@
|
||||
#define FF_INVALID_FD (-1)
|
||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||
// 8192 comes from procps-ng: https://gitlab.com/procps-ng/procps/-/blob/master/library/meminfo.c?ref_type=heads#L39
|
||||
#define PROC_FILE_BUFFSIZ 8192
|
||||
#define PROC_FILE_BUFFSIZ (32 * 1024)
|
||||
#endif
|
||||
|
||||
static inline FFNativeFD FFUnixFD2NativeFD(int unixfd)
|
||||
|
||||
@@ -279,8 +279,10 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
||||
psinfo_t proc;
|
||||
if (ffReadFileData(filePath, sizeof(proc), &proc) == sizeof(proc))
|
||||
{
|
||||
ffStrbufSetS(exe, proc.pr_psargs);
|
||||
ffStrbufSubstrBeforeFirstC(exe, ' ');
|
||||
const char* args = proc.pr_psargs;
|
||||
if (args[0] == '-') ++args;
|
||||
const char* end = strchr(args, ' ');
|
||||
ffStrbufSetNS(exe, end ? (uint32_t) (end - args) : (uint32_t) strlen(args), args);
|
||||
}
|
||||
|
||||
if (exePath)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
use scripting additions
|
||||
use framework "/System/Library/PrivateFrameworks/MediaRemote.framework"
|
||||
|
||||
set MRNowPlayingRequest to current application's NSClassFromString("MRNowPlayingRequest")
|
||||
|
||||
if MRNowPlayingRequest's localNowPlayingItem() is missing value then
|
||||
return
|
||||
end if
|
||||
|
||||
if MRNowPlayingRequest's localIsPlaying() then
|
||||
set status to "Playing"
|
||||
else
|
||||
set status to "Paused"
|
||||
end if
|
||||
|
||||
set infoDict to MRNowPlayingRequest's localNowPlayingItem()'s nowPlayingInfo()
|
||||
set bundleObj to MRNowPlayingRequest's localNowPlayingPlayerPath()'s client()
|
||||
|
||||
return status & "
|
||||
" & (infoDict's valueForKey:"kMRMediaRemoteNowPlayingInfoTitle" as text) & "
|
||||
" & (infoDict's valueForKey:"kMRMediaRemoteNowPlayingInfoArtist" as text) & "
|
||||
" & (infoDict's valueForKey:"kMRMediaRemoteNowPlayingInfoAlbum" as text) & "
|
||||
" & (bundleObj's bundleIdentifier() as text) & "
|
||||
" & (bundleObj's displayName() as text)
|
||||
@@ -32,6 +32,10 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#elif __sun
|
||||
#include <libdevinfo.h>
|
||||
#include <sys/sunddi.h>
|
||||
#endif
|
||||
|
||||
typedef struct FFSmbiosBios
|
||||
@@ -59,6 +63,7 @@ typedef struct FFSmbiosBios
|
||||
static_assert(offsetof(FFSmbiosBios, ExtendedBiosRomSize) == 0x18,
|
||||
"FFSmbiosBios: Wrong struct alignment");
|
||||
|
||||
|
||||
const char* ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
@@ -94,6 +99,17 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#elif __sun
|
||||
di_node_t rootNode = di_init("/", DINFOPROP);
|
||||
if (rootNode != DI_NODE_NIL)
|
||||
{
|
||||
char* efiVersion = NULL;
|
||||
if (di_prop_lookup_strings(DDI_DEV_T_ANY, rootNode, "efi-version", &efiVersion) > 0)
|
||||
ffStrbufSetStatic(&bios->type, "UEFI");
|
||||
else
|
||||
ffStrbufSetStatic(&bios->type, "BIOS");
|
||||
}
|
||||
di_fini(rootNode);
|
||||
#elif __HAIKU__ || __OpenBSD__
|
||||
// Currently SMBIOS detection is supported in legancy BIOS only
|
||||
ffStrbufSetStatic(&bios->type, "BIOS");
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "util/smbiosHelper.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include "perflib_.h"
|
||||
#include "util/windows/perflib_.h"
|
||||
#include <wchar.h>
|
||||
|
||||
static inline void ffPerfCloseQueryHandle(HANDLE* phQuery)
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
#include <stdint.h>
|
||||
|
||||
static FFlist cpuTimes1;
|
||||
static uint64_t startTime;
|
||||
|
||||
void ffPrepareCPUUsage(void)
|
||||
{
|
||||
assert(cpuTimes1.elementSize == 0);
|
||||
ffListInit(&cpuTimes1, sizeof(FFCpuUsageInfo));
|
||||
ffGetCpuUsageInfo(&cpuTimes1);
|
||||
startTime = ffTimeGetNow();
|
||||
}
|
||||
|
||||
const char* ffGetCpuUsageResult(FFCPUUsageOptions* options, FFlist* result)
|
||||
@@ -23,6 +25,12 @@ const char* ffGetCpuUsageResult(FFCPUUsageOptions* options, FFlist* result)
|
||||
if(error) return error;
|
||||
ffTimeSleep(options->waitTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t elapsedTime = ffTimeGetNow() - startTime;
|
||||
if (elapsedTime < options->waitTime)
|
||||
ffTimeSleep(options->waitTime - (uint32_t)elapsedTime);
|
||||
}
|
||||
|
||||
if(cpuTimes1.length == 0) return "No CPU cores found";
|
||||
|
||||
@@ -57,5 +65,6 @@ retry:
|
||||
cpuTime1->inUseAll = cpuTime2->inUseAll;
|
||||
cpuTime1->totalAll = cpuTime2->totalAll;
|
||||
}
|
||||
startTime = ffTimeGetNow();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
for (uint32_t i = 0; i < coreCount; ++i)
|
||||
{
|
||||
uint64_t* cpTime = cpTimes[i];
|
||||
uint64_t inUse = cpTime[CP_USER] + cpTime[CP_NICE] + cpTime[CP_SYS];
|
||||
uint64_t total = inUse + cpTime[CP_INTR] + cpTime[CP_IDLE];
|
||||
uint64_t inUse = cpTime[CP_USER] + cpTime[CP_NICE] + cpTime[CP_SYS] + cpTime[CP_INTR];
|
||||
uint64_t total = inUse + cpTime[CP_IDLE];
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
|
||||
@@ -31,8 +31,8 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
if(sscanf(start, "cpu%*d%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%*[^\n]\n", &user, &nice, &system, &idle, &iowait, &irq, &softirq) == 7)
|
||||
{
|
||||
uint64_t inUse = user + nice + system;
|
||||
uint64_t total = inUse + idle + iowait + irq + softirq;
|
||||
uint64_t inUse = user + nice + system + irq + softirq;
|
||||
uint64_t total = inUse + idle + iowait;
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#include "util/windows/perflib_.h"
|
||||
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
static const char* getInfoByNqsi(FFlist* cpuTimes)
|
||||
{
|
||||
ULONG size = 0;
|
||||
if(NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
|
||||
@@ -20,11 +23,8 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* coreInfo = pinfo + i;
|
||||
|
||||
// KernelTime includes idle time.
|
||||
LONGLONG dpcTime = coreInfo->Reserved1[0].QuadPart;
|
||||
LONGLONG interruptTime = coreInfo->Reserved1[1].QuadPart;
|
||||
// KernelTime includes IdleTime and DpcTime.
|
||||
coreInfo->KernelTime.QuadPart -= coreInfo->IdleTime.QuadPart;
|
||||
coreInfo->KernelTime.QuadPart += dpcTime + interruptTime;
|
||||
|
||||
uint64_t inUse = (uint64_t) (coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart);
|
||||
uint64_t total = inUse + (uint64_t)coreInfo->IdleTime.QuadPart;
|
||||
@@ -38,3 +38,137 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* getInfoByPerflib(FFlist* cpuTimes)
|
||||
{
|
||||
static HANDLE hQuery = NULL;
|
||||
|
||||
if (hQuery == NULL)
|
||||
{
|
||||
struct FFPerfQuerySpec
|
||||
{
|
||||
PERF_COUNTER_IDENTIFIER Identifier;
|
||||
WCHAR Name[16];
|
||||
} querySpec = {
|
||||
.Identifier = {
|
||||
// Processor Information GUID
|
||||
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\_V2Providers\{383487a6-3676-4870-a4e7-d45b30c35629}\{b4fc721a-0378-476f-89ba-a5a79f810b36}
|
||||
.CounterSetGuid = { 0xb4fc721a, 0x0378, 0x476f, {0x89, 0xba, 0xa5, 0xa7, 0x9f, 0x81, 0x0b, 0x36} },
|
||||
.Size = sizeof(querySpec),
|
||||
.CounterId = PERF_WILDCARD_COUNTER, // https://learn.microsoft.com/en-us/windows/win32/perfctrs/using-the-perflib-functions-to-consume-counter-data
|
||||
.InstanceId = PERF_WILDCARD_COUNTER,
|
||||
},
|
||||
.Name = PERF_WILDCARD_INSTANCE,
|
||||
};
|
||||
|
||||
if (PerfOpenQueryHandle(NULL, &hQuery) != ERROR_SUCCESS)
|
||||
{
|
||||
PerfCloseQueryHandle(hQuery);
|
||||
hQuery = INVALID_HANDLE_VALUE;
|
||||
return "PerfOpenQueryHandle() failed";
|
||||
}
|
||||
|
||||
if (PerfAddCounters(hQuery, &querySpec.Identifier, sizeof(querySpec)) != ERROR_SUCCESS)
|
||||
{
|
||||
PerfCloseQueryHandle(hQuery);
|
||||
hQuery = INVALID_HANDLE_VALUE;
|
||||
return "PerfAddCounters() failed";
|
||||
}
|
||||
|
||||
if (querySpec.Identifier.Status != ERROR_SUCCESS)
|
||||
{
|
||||
PerfCloseQueryHandle(hQuery);
|
||||
hQuery = INVALID_HANDLE_VALUE;
|
||||
return "PerfAddCounters() reports invalid identifier";
|
||||
}
|
||||
}
|
||||
|
||||
if (hQuery == INVALID_HANDLE_VALUE)
|
||||
return "Init hQuery failed";
|
||||
|
||||
DWORD dataSize = 0;
|
||||
if (PerfQueryCounterData(hQuery, NULL, 0, &dataSize) != ERROR_NOT_ENOUGH_MEMORY)
|
||||
return "PerfQueryCounterData(NULL) failed";
|
||||
|
||||
if (dataSize <= sizeof(PERF_DATA_HEADER) + sizeof(PERF_COUNTER_HEADER))
|
||||
return "instance doesn't exist";
|
||||
|
||||
FF_AUTO_FREE PERF_DATA_HEADER* const pDataHeader = (PERF_DATA_HEADER*)malloc(dataSize);
|
||||
if (PerfQueryCounterData(hQuery, pDataHeader, dataSize, &dataSize) != ERROR_SUCCESS)
|
||||
return "PerfQueryCounterData(pDataHeader) failed";
|
||||
|
||||
PERF_COUNTER_HEADER* pCounterHeader = (PERF_COUNTER_HEADER*)(pDataHeader + 1);
|
||||
if (pCounterHeader->dwType != PERF_COUNTERSET)
|
||||
return "Invalid counter type";
|
||||
|
||||
PERF_MULTI_COUNTERS* pMultiCounters = (PERF_MULTI_COUNTERS*)(pCounterHeader + 1);
|
||||
if (pMultiCounters->dwCounters == 0)
|
||||
return "No CPU counters found";
|
||||
|
||||
PERF_MULTI_INSTANCES* pMultiInstances = (PERF_MULTI_INSTANCES*)((BYTE*)pMultiCounters + pMultiCounters->dwSize);
|
||||
if (pMultiInstances->dwInstances == 0)
|
||||
return "No CPU instances found";
|
||||
|
||||
PERF_INSTANCE_HEADER* pInstanceHeader = (PERF_INSTANCE_HEADER*)(pMultiInstances + 1);
|
||||
for (DWORD iInstance = 0; iInstance < pMultiInstances->dwInstances; ++iInstance)
|
||||
{
|
||||
const wchar_t* instanceName = (const wchar_t*)((BYTE*)pInstanceHeader + sizeof(*pInstanceHeader));
|
||||
|
||||
PERF_COUNTER_DATA* pCounterData = (PERF_COUNTER_DATA*)((BYTE*)pInstanceHeader + pInstanceHeader->Size);
|
||||
|
||||
uint64_t processorUtility = UINT64_MAX, utilityBase = UINT64_MAX;
|
||||
for (ULONG iCounter = 0; iCounter != pMultiCounters->dwCounters; iCounter++)
|
||||
{
|
||||
DWORD* pCounterIds = (DWORD*)(pMultiCounters + 1);
|
||||
// https://learn.microsoft.com/en-us/windows/win32/perfctrs/using-the-perflib-functions-to-consume-counter-data
|
||||
switch (pCounterIds[iCounter]) {
|
||||
case 26: // % Processor Utility (#26, Type=PERF_AVERAGE_BULK)
|
||||
assert(pCounterData->dwDataSize == sizeof(uint64_t));
|
||||
processorUtility = *(uint64_t*)(pCounterData + 1);
|
||||
break;
|
||||
case 27: // % Utility Base (#27, Type=PERF_AVERAGE_BASE)
|
||||
assert(pCounterData->dwDataSize == sizeof(uint32_t));
|
||||
utilityBase = *(uint32_t*)(pCounterData + 1) * 100LLU;
|
||||
break;
|
||||
}
|
||||
|
||||
pCounterData = (PERF_COUNTER_DATA*)((BYTE*)pCounterData + pCounterData->dwSize);
|
||||
}
|
||||
|
||||
if (wcschr(instanceName, L'_') == NULL /* ignore `_Total` */)
|
||||
{
|
||||
if (processorUtility == UINT64_MAX)
|
||||
return "Counter \"% Processor Utility\" are not supported";
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = processorUtility,
|
||||
.totalAll = utilityBase,
|
||||
};
|
||||
}
|
||||
|
||||
pInstanceHeader = (PERF_INSTANCE_HEADER*)pCounterData;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
#if __aarch64__
|
||||
static uint8_t winver = 10; // Assume Windows 10 or later for WoA
|
||||
#else
|
||||
static uint8_t winver = 0;
|
||||
if (winver == 0)
|
||||
winver = (uint8_t) ffStrbufToUInt(&instance.state.platform.sysinfo.release, 1);
|
||||
#endif
|
||||
|
||||
if (winver >= 10)
|
||||
{
|
||||
if (getInfoByPerflib(cpuTimes) == NULL) return NULL;
|
||||
ffListClear(cpuTimes);
|
||||
winver = 1; // Fall back to NQSI
|
||||
}
|
||||
|
||||
return getInfoByNqsi(cpuTimes);
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
|
||||
#endif
|
||||
|
||||
const char* ffdsConnectDrm(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectDrm(FF_MAYBE_UNUSED FFDisplayServerResult* result)
|
||||
{
|
||||
#ifdef FF_HAVE_DRM
|
||||
if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
|
||||
|
||||
@@ -212,11 +212,13 @@ static const char* detectByPci(const FFGPUOptions* options, FFlist* gpus)
|
||||
|
||||
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
#if FF_HAVE_DRM
|
||||
if (options->detectionMethod == FF_GPU_DETECTION_METHOD_AUTO)
|
||||
{
|
||||
detectByDrm(options, gpus);
|
||||
if (gpus->length > 0) return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return detectByPci(options, gpus);
|
||||
}
|
||||
|
||||
@@ -45,8 +45,10 @@ static const FFstrbuf* loadPciIds()
|
||||
if (pciids.length == 0)
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", &pciids);
|
||||
}
|
||||
#elif __FreeBSD__ || __OpenBSD__ || __NetBSD__
|
||||
#elif __FreeBSD__ || __NetBSD__
|
||||
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", &pciids);
|
||||
#elif __OpenBSD__
|
||||
ffReadFileBuffer(_PATH_LOCALBASE "/share/hwdata/pci.ids", &pciids);
|
||||
#elif __sun
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
|
||||
#elif __HAIKU__
|
||||
|
||||
@@ -1,83 +1,57 @@
|
||||
#include "gpu.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
#include <libdevinfo.h>
|
||||
|
||||
static int walkDevTree(di_node_t node, FF_MAYBE_UNUSED di_minor_t minor, FFlist* gpus)
|
||||
{
|
||||
// SunOS requires root permission to query PCI device list, except `/usr/bin/scanpci`
|
||||
// Same behavior can be observed with `cp $(which scanpci) /tmp/ && /tmp/scanpci`
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
|
||||
"/usr/bin/scanpci",
|
||||
"-v",
|
||||
NULL,
|
||||
});
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!ffStrbufStartsWithS(&buffer, "\npci "))
|
||||
return "Invalid scanpci result";
|
||||
|
||||
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
|
||||
// Device unknown
|
||||
// CardVendor 0x0000 card 0x0000 (Card unknown)
|
||||
// STATUS 0x0010 COMMAND 0x0007
|
||||
// CLASS 0x03 0x02 0x00 REVISION 0x00
|
||||
// BIST 0x00 HEADER 0x00 LATENCY 0x00 CACHE 0x00
|
||||
// MAX_LAT 0x00 MIN_GNT 0x00 INT_PIN 0x00 INT_LINE 0x00
|
||||
|
||||
for (
|
||||
const char* pclass = strstr(buffer.chars, "\n CLASS 0x03 ");
|
||||
pclass;
|
||||
pclass = strstr(pclass, "\n CLASS 0x03 ")
|
||||
)
|
||||
int* vendorId;
|
||||
int* deviceId;
|
||||
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "vendor-id", &vendorId) > 0
|
||||
&& di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-id", &deviceId) > 0)
|
||||
{
|
||||
// find the start of device entry
|
||||
const char* pstart = memrchr(buffer.chars, '\n', (size_t) (pclass - buffer.chars));
|
||||
if (pstart == NULL)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
while (pstart[1] != 'p')
|
||||
{
|
||||
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
|
||||
if (pstart == NULL)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
}
|
||||
++pstart;
|
||||
|
||||
uint32_t vendorId, deviceId;
|
||||
if (sscanf(pstart, "pci %*[^:]: vendor %x device %x",
|
||||
&vendorId, &deviceId) != 2)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
|
||||
pclass += strlen("\n CLASS 0x03 ");
|
||||
uint32_t subclass = (uint32_t) strtoul(pclass, NULL, 16);
|
||||
pclass += strlen("0x02 0x00 REVISION ");
|
||||
uint32_t revision = (uint32_t) strtoul(pclass, NULL, 16);
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
ffStrbufInitS(&gpu->vendor, ffGPUGetVendorString((uint16_t) *vendorId));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "/usr/bin/scanpci");
|
||||
ffStrbufInitS(&gpu->driver, di_driver_name(node));
|
||||
ffStrbufInitStatic(&gpu->platformApi, "libdevinfo");
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = 0;
|
||||
gpu->deviceId = strtoul(di_bus_addr(node), NULL, 16);
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
|
||||
ffGPUQueryAmdGpuName((uint16_t) deviceId, (uint8_t) revision, gpu);
|
||||
{
|
||||
int* revId;
|
||||
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "revision-id", &revId) > 0)
|
||||
ffGPUQueryAmdGpuName((uint16_t) *deviceId, (uint8_t) *revId, gpu);
|
||||
}
|
||||
|
||||
if (gpu->name.length == 0)
|
||||
{
|
||||
ffGPUFillVendorAndName((uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
uint8_t subclass = 0; // assume VGA
|
||||
int* classCode;
|
||||
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "class-code", &classCode) > 0)
|
||||
subclass = (uint8_t) (*classCode & 0xFFFF);
|
||||
ffGPUFillVendorAndName(subclass, (uint16_t) *vendorId, (uint16_t) *deviceId, gpu);
|
||||
}
|
||||
}
|
||||
|
||||
return DI_WALK_CONTINUE;
|
||||
}
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
di_node_t rootNode = di_init("/", DINFOCPYALL);
|
||||
if (rootNode == DI_NODE_NIL)
|
||||
return "di_init() failed";
|
||||
di_walk_minor(rootNode, DDI_NT_DISPLAY, DI_WALK_CLDFIRST, gpus, (void*) walkDevTree);
|
||||
di_fini(rootNode);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,35 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/media/media.h"
|
||||
#include "common/library.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/apple/osascript.h"
|
||||
#include "fastfetch_datatext.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
// https://github.com/andrewwiik/iOS-Blocks/blob/master/Widgets/Music/MediaRemote.h
|
||||
extern void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t dispatcher, void(^callback)(_Nullable CFDictionaryRef info)) __attribute__((weak_import));
|
||||
extern void MRMediaRemoteGetNowPlayingClient(dispatch_queue_t dispatcher, void (^callback)(_Nullable id clientObj)) __attribute__((weak_import));
|
||||
extern CFStringRef MRNowPlayingClientGetBundleIdentifier(id clientObj) __attribute__((weak_import));
|
||||
extern CFStringRef MRNowPlayingClientGetParentAppBundleIdentifier(id clientObj) __attribute__((weak_import));
|
||||
void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, void (^callback)(BOOL playing)) __attribute__((weak_import));
|
||||
extern void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, void (^callback)(BOOL playing)) __attribute__((weak_import));
|
||||
extern void MRMediaRemoteGetNowPlayingApplicationDisplayID(dispatch_queue_t queue, void (^callback)(_Nullable CFStringRef displayID)) __attribute__((weak_import));
|
||||
extern void MRMediaRemoteGetNowPlayingApplicationDisplayName(int unknown, dispatch_queue_t queue, void (^callback)(_Nullable CFStringRef name)) __attribute__((weak_import));
|
||||
|
||||
static const char* getMediaByMediaRemote(FFMediaResult* result)
|
||||
{
|
||||
#define FF_TEST_FN_EXISTANCE(fn) if (!fn) return "MediaRemote function " #fn " is not available"
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingInfo);
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingClient);
|
||||
FF_TEST_FN_EXISTANCE(MRNowPlayingClientGetBundleIdentifier);
|
||||
FF_TEST_FN_EXISTANCE(MRNowPlayingClientGetParentAppBundleIdentifier);
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingApplicationIsPlaying);
|
||||
#undef FF_TEST_FN_EXISTANCE
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingApplicationIsPlaying(queue, ^(BOOL playing) {
|
||||
ffStrbufSetStatic(&result->status, playing ? "Playing" : "Paused");
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
__block const char* error = NULL;
|
||||
MRMediaRemoteGetNowPlayingInfo(queue, ^(_Nullable CFDictionaryRef info) {
|
||||
if(info != nil)
|
||||
{
|
||||
error = ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
if(!error)
|
||||
{
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
}
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
}
|
||||
else
|
||||
error = "MRMediaRemoteGetNowPlayingInfo() failed";
|
||||
@@ -53,42 +38,76 @@ static const char* getMediaByMediaRemote(FFMediaResult* result)
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingClient(queue, ^(_Nullable id clientObj) {
|
||||
if (clientObj != nil)
|
||||
{
|
||||
CFStringRef identifier = MRNowPlayingClientGetBundleIdentifier(clientObj);
|
||||
if (identifier == nil)
|
||||
identifier = MRNowPlayingClientGetParentAppBundleIdentifier(clientObj);
|
||||
if (identifier != nil)
|
||||
ffCfStrGetString(identifier, &result->playerId);
|
||||
}
|
||||
MRMediaRemoteGetNowPlayingApplicationIsPlaying(queue, ^(BOOL playing) {
|
||||
ffStrbufSetStatic(&result->status, playing ? "Playing" : "Paused");
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
if (MRMediaRemoteGetNowPlayingApplicationDisplayID)
|
||||
{
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingApplicationDisplayID(queue, ^(_Nullable CFStringRef displayID) {
|
||||
ffCfStrGetString(displayID, &result->playerId);
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
}
|
||||
|
||||
if (MRMediaRemoteGetNowPlayingApplicationDisplayName)
|
||||
{
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingApplicationDisplayName(0, queue, ^(_Nullable CFStringRef name) {
|
||||
ffCfStrGetString(name, &result->player);
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
}
|
||||
|
||||
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
||||
// Don't dispatch_release because we are using ARC
|
||||
|
||||
if(result->playerId.length > 0)
|
||||
{
|
||||
char buf[128];
|
||||
snprintf(buf, ARRAY_SIZE(buf), "name of app id \"%s\"", result->playerId.chars);
|
||||
ffOsascript(buf, &result->player);
|
||||
}
|
||||
|
||||
if(result->song.length > 0)
|
||||
return NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static const char* getMediaByOsascript(FFMediaResult* result)
|
||||
__attribute__((visibility("default"), used))
|
||||
int ffPrintMediaByMediaRemote(void)
|
||||
{
|
||||
FFMediaResult media = {
|
||||
.status = ffStrbufCreate(),
|
||||
.song = ffStrbufCreate(),
|
||||
.artist = ffStrbufCreate(),
|
||||
.album = ffStrbufCreate(),
|
||||
.playerId = ffStrbufCreate(),
|
||||
.player = ffStrbufCreate(),
|
||||
};
|
||||
if (getMediaByMediaRemote(&media) != NULL)
|
||||
return 1;
|
||||
ffStrbufPutTo(&media.status, stdout);
|
||||
ffStrbufPutTo(&media.song, stdout);
|
||||
ffStrbufPutTo(&media.artist, stdout);
|
||||
ffStrbufPutTo(&media.album, stdout);
|
||||
ffStrbufPutTo(&media.playerId, stdout);
|
||||
ffStrbufPutTo(&media.player, stdout);
|
||||
ffStrbufDestroy(&media.status);
|
||||
ffStrbufDestroy(&media.song);
|
||||
ffStrbufDestroy(&media.artist);
|
||||
ffStrbufDestroy(&media.album);
|
||||
ffStrbufDestroy(&media.playerId);
|
||||
ffStrbufDestroy(&media.player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* getMediaByAuthorizedProcess(FFMediaResult* result)
|
||||
{
|
||||
// #1737
|
||||
FF_STRBUF_AUTO_DESTROY script = ffStrbufCreateF("import ctypes;ctypes.CDLL('%s').ffPrintMediaByMediaRemote()", instance.state.platform.exePath.chars);
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
// The script must be executed by `/usr/bin/osascript`. `ffOsascript` doesn't work here
|
||||
|
||||
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
|
||||
"/usr/bin/osascript",
|
||||
"-e",
|
||||
FASTFETCH_DATATEXT_NOWPLAYING,
|
||||
"/usr/bin/python3", // Must be signed by Apple. Homebrew python doesn't work
|
||||
"-c",
|
||||
script.chars,
|
||||
nil
|
||||
});
|
||||
if (error) return error;
|
||||
@@ -107,8 +126,16 @@ void ffDetectMediaImpl(FFMediaResult* media)
|
||||
{
|
||||
const char* error;
|
||||
if (@available(macOS 15.4, *))
|
||||
error = getMediaByOsascript(media);
|
||||
error = getMediaByAuthorizedProcess(media);
|
||||
else
|
||||
error = getMediaByMediaRemote(media);
|
||||
if (error) ffStrbufAppendS(&media->error, error);
|
||||
if (error)
|
||||
ffStrbufAppendS(&media->error, error);
|
||||
else if (media->player.length == 0 && media->playerId.length > 0)
|
||||
{
|
||||
ffStrbufSet(&media->player, &media->playerId);
|
||||
if (ffStrbufStartsWithIgnCaseS(&media->player, "com."))
|
||||
ffStrbufSubstrAfter(&media->player, strlen("com.") - 1);
|
||||
ffStrbufReplaceAllC(&media->player, '.', ' ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@ static void parseSystemVersion(FFOSResult* os)
|
||||
ffStrbufInitS(&os->version, value.UTF8String);
|
||||
if((value = dict[@"ProductBuildVersion"]))
|
||||
ffStrbufInitS(&os->buildID, value.UTF8String);
|
||||
if (ffStrbufStartsWithS(&os->version, "16."))
|
||||
{
|
||||
// macOS 26 Tahoe. #1809
|
||||
os->version.chars[0] = '2';
|
||||
}
|
||||
}
|
||||
|
||||
static bool detectOSCodeName(FFOSResult* os)
|
||||
@@ -64,7 +69,7 @@ static bool detectOSCodeName(FFOSResult* os)
|
||||
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
|
||||
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
|
||||
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
|
||||
case 3: ffStrbufSetStatic(&os->codename, "Panther"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 3: ffStrbufSetStatic(&os->codename, "Panther"); return true;
|
||||
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
|
||||
case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
|
||||
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
|
||||
|
||||
+85
-68
@@ -47,7 +47,7 @@ FF_MAYBE_UNUSED static bool detectArmbianVersion(FFOSResult* result)
|
||||
// - `Armbian_Security` for images with kali repo added
|
||||
// - `Armbian-unofficial` for an unofficial image built from source, e.g. during development and testing
|
||||
if (ffStrbufStartsWithS(&result->prettyName, "Armbian"))
|
||||
ffStrbufSetS(&result->name, "Armbian");
|
||||
ffStrbufSetStatic(&result->name, "Armbian");
|
||||
else
|
||||
return false;
|
||||
ffStrbufSet(&result->idLike, &result->id);
|
||||
@@ -69,113 +69,113 @@ FF_MAYBE_UNUSED static void getUbuntuFlavour(FFOSResult* result)
|
||||
return;
|
||||
else if(ffStrbufStartsWithS(&result->prettyName, "Linux Lite "))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Linux Lite");
|
||||
ffStrbufSetS(&result->id, "linuxlite");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Linux Lite");
|
||||
ffStrbufSetStatic(&result->id, "linuxlite");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Linux Lite "));
|
||||
return;
|
||||
}
|
||||
else if(ffStrbufStartsWithS(&result->prettyName, "Rhino Linux "))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Rhino Linux");
|
||||
ffStrbufSetS(&result->id, "rhinolinux");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Rhino Linux");
|
||||
ffStrbufSetStatic(&result->id, "rhinolinux");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Rhino Linux "));
|
||||
return;
|
||||
}
|
||||
else if(ffStrbufStartsWithS(&result->prettyName, "VanillaOS "))
|
||||
{
|
||||
ffStrbufSetS(&result->id, "vanilla");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->id, "vanilla");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "kde") || ffStrContains(xdgConfigDirs, "plasma") || ffStrContains(xdgConfigDirs, "kubuntu"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Kubuntu");
|
||||
ffStrbufSetS(&result->prettyName, "Kubuntu");
|
||||
ffStrbufSetS(&result->id, "kubuntu");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Kubuntu");
|
||||
ffStrbufSetF(&result->prettyName, "Kubuntu %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "kubuntu");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "xfce") || ffStrContains(xdgConfigDirs, "xubuntu"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Xubuntu");
|
||||
ffStrbufSetS(&result->prettyName, "Xubuntu");
|
||||
ffStrbufSetS(&result->id, "xubuntu");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Xubuntu");
|
||||
ffStrbufSetF(&result->prettyName, "Xubuntu %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "xubuntu");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "lxqt") || ffStrContains(xdgConfigDirs, "lubuntu"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Lubuntu");
|
||||
ffStrbufSetS(&result->prettyName, "Lubuntu");
|
||||
ffStrbufSetS(&result->id, "lubuntu");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Lubuntu");
|
||||
ffStrbufSetF(&result->prettyName, "Lubuntu %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "lubuntu");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "budgie"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Ubuntu Budgie");
|
||||
ffStrbufSetS(&result->prettyName, "Ubuntu Budgie");
|
||||
ffStrbufSetS(&result->id, "ubuntu-budgie");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Ubuntu Budgie");
|
||||
ffStrbufSetF(&result->prettyName, "Ubuntu Budgie %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "ubuntu-budgie");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "cinnamon"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Ubuntu Cinnamon");
|
||||
ffStrbufSetS(&result->prettyName, "Ubuntu Cinnamon");
|
||||
ffStrbufSetS(&result->id, "ubuntu-cinnamon");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Ubuntu Cinnamon");
|
||||
ffStrbufSetF(&result->prettyName, "Ubuntu Cinnamon %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "ubuntu-cinnamon");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "mate"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Ubuntu MATE");
|
||||
ffStrbufSetS(&result->prettyName, "Ubuntu MATE");
|
||||
ffStrbufSetS(&result->id, "ubuntu-mate");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Ubuntu MATE");
|
||||
ffStrbufSetF(&result->prettyName, "Ubuntu MATE %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "ubuntu-mate");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "studio"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Ubuntu Studio");
|
||||
ffStrbufSetS(&result->prettyName, "Ubuntu Studio");
|
||||
ffStrbufSetS(&result->id, "ubuntu-studio");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Ubuntu Studio");
|
||||
ffStrbufSetF(&result->prettyName, "Ubuntu Studio %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "ubuntu-studio");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "sway"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Ubuntu Sway");
|
||||
ffStrbufSetS(&result->prettyName, "Ubuntu Sway");
|
||||
ffStrbufSetS(&result->id, "ubuntu-sway");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Ubuntu Sway");
|
||||
ffStrbufSetF(&result->prettyName, "Ubuntu Sway %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "ubuntu-sway");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "touch"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "Ubuntu Touch");
|
||||
ffStrbufSetS(&result->prettyName, "Ubuntu Touch");
|
||||
ffStrbufSetS(&result->id, "ubuntu-touch");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "Ubuntu Touch");
|
||||
ffStrbufSetF(&result->prettyName, "Ubuntu Touch %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "ubuntu-touch");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrContains(xdgConfigDirs, "lliurex"))
|
||||
{
|
||||
ffStrbufSetS(&result->name, "LliureX");
|
||||
ffStrbufSetS(&result->prettyName, "LliureX");
|
||||
ffStrbufSetS(&result->id, "lliurex");
|
||||
ffStrbufSetS(&result->idLike, "ubuntu");
|
||||
ffStrbufSetStatic(&result->name, "LliureX");
|
||||
ffStrbufSetF(&result->prettyName, "LliureX %s", result->version.chars);
|
||||
ffStrbufSetStatic(&result->id, "lliurex");
|
||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -196,8 +196,8 @@ FF_MAYBE_UNUSED static bool detectDebianDerived(FFOSResult* result)
|
||||
return true;
|
||||
else if (ffStrbufStartsWithS(&result->name, "Loc-OS"))
|
||||
{
|
||||
ffStrbufSetS(&result->id, "locos");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetStatic(&result->id, "locos");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
return true;
|
||||
}
|
||||
else if (ffStrbufEqualS(&result->name, "Parrot Security"))
|
||||
@@ -210,15 +210,15 @@ FF_MAYBE_UNUSED static bool detectDebianDerived(FFOSResult* result)
|
||||
else if (ffStrbufStartsWithS(&result->name, "Lilidog GNU/Linux"))
|
||||
{
|
||||
// https://github.com/fastfetch-cli/fastfetch/issues/1373
|
||||
ffStrbufSetS(&result->id, "lilidog");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetStatic(&result->id, "lilidog");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
return true;
|
||||
}
|
||||
else if (access("/usr/bin/pveversion", X_OK) == 0)
|
||||
{
|
||||
ffStrbufSetS(&result->id, "pve");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetS(&result->name, "Proxmox VE");
|
||||
ffStrbufSetStatic(&result->id, "pve");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
ffStrbufSetStatic(&result->name, "Proxmox VE");
|
||||
ffStrbufClear(&result->versionID);
|
||||
if (ffProcessAppendStdOut(&result->versionID, (char* const[]) {
|
||||
"/usr/bin/dpkg-query",
|
||||
@@ -231,22 +231,39 @@ FF_MAYBE_UNUSED static bool detectDebianDerived(FFOSResult* result)
|
||||
ffStrbufSetF(&result->prettyName, "Proxmox VE %s", result->versionID.chars);
|
||||
return true;
|
||||
}
|
||||
else if (ffStrbufContainS(&instance.state.platform.sysinfo.release, "+rpt-rpi-"))
|
||||
else if (ffPathExists("/etc/rpi-issue", FF_PATHTYPE_FILE))
|
||||
{
|
||||
// Raspberry Pi OS
|
||||
ffStrbufSetS(&result->id, "raspbian");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetS(&result->name, "Raspberry Pi OS");
|
||||
ffStrbufSetS(&result->prettyName, "Raspberry Pi OS");
|
||||
ffStrbufSetStatic(&result->id, "raspbian");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
ffStrbufSetStatic(&result->name, "Raspberry Pi OS");
|
||||
ffStrbufSetStatic(&result->prettyName, "Raspberry Pi OS");
|
||||
return true;
|
||||
}
|
||||
else if (ffPathExists("/boot/dietpi/.version", FF_PATHTYPE_FILE))
|
||||
{
|
||||
// DietPi
|
||||
ffStrbufSetStatic(&result->id, "dietpi");
|
||||
ffStrbufSetStatic(&result->name, "DietPi");
|
||||
ffStrbufSetStatic(&result->prettyName, "DietPi");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
FF_STRBUF_AUTO_DESTROY core = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY sub = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY rc = ffStrbufCreate();
|
||||
if (ffParsePropFileValues("/boot/dietpi/.version", 3, (FFpropquery[]) {
|
||||
{"G_DIETPI_VERSION_CORE=", &core},
|
||||
{"G_DIETPI_VERSION_SUB=", &sub},
|
||||
{"G_DIETPI_VERSION_RC=", &rc},
|
||||
})) ffStrbufAppendF(&result->prettyName, " %s.%s.%s", core.chars, sub.chars, rc.chars);
|
||||
return true;
|
||||
}
|
||||
else if (ffStrbufEndsWithS(&instance.state.platform.sysinfo.release, "+truenas"))
|
||||
{
|
||||
// TrueNAS Scale
|
||||
ffStrbufSetS(&result->id, "truenas-scale");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetS(&result->name, "TrueNAS Scale");
|
||||
ffStrbufSetS(&result->prettyName, "TrueNAS Scale");
|
||||
ffStrbufSetStatic(&result->id, "truenas-scale");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
ffStrbufSetStatic(&result->name, "TrueNAS Scale");
|
||||
ffStrbufSetStatic(&result->prettyName, "TrueNAS Scale");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -255,9 +272,9 @@ FF_MAYBE_UNUSED static bool detectDebianDerived(FFOSResult* result)
|
||||
FF_STRBUF_AUTO_DESTROY lsbRelease = ffStrbufCreate();
|
||||
if (ffAppendFileBuffer("/etc/lsb-release", &lsbRelease) && ffStrbufContainS(&lsbRelease, "DISTRIB_ID=MX"))
|
||||
{
|
||||
ffStrbufSetS(&result->id, "mx");
|
||||
ffStrbufSetS(&result->idLike, "debian");
|
||||
ffStrbufSetS(&result->name, "MX");
|
||||
ffStrbufSetStatic(&result->id, "mx");
|
||||
ffStrbufSetStatic(&result->idLike, "debian");
|
||||
ffStrbufSetStatic(&result->name, "MX");
|
||||
|
||||
ffStrbufClear(&result->version);
|
||||
ffParsePropLines(lsbRelease.chars, "DISTRIB_RELEASE=", &result->version);
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "sys/scsi/generic/inquiry.h"
|
||||
|
||||
#include <libdevinfo.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct FFWalkTreeBundle
|
||||
{
|
||||
FFPhysicalDiskOptions* options;
|
||||
FFlist* disks;
|
||||
};
|
||||
|
||||
static int walkDevTree(di_node_t node, di_minor_t minor, struct FFWalkTreeBundle* bundle)
|
||||
{
|
||||
if (di_minor_spectype(minor) != S_IFCHR || !ffStrEquals(di_minor_name(minor), "a,raw")) return DI_WALK_CONTINUE;
|
||||
|
||||
char* productId;
|
||||
char* vendorId;
|
||||
if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-product-id", &productId) > 0
|
||||
&& di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-vendor-id", &vendorId) > 0)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateF("%s %s", vendorId, productId);
|
||||
if (bundle->options->namePrefix.length && !ffStrbufStartsWithIgnCase(&name, &bundle->options->namePrefix))
|
||||
return DI_WALK_CONTINUE;
|
||||
|
||||
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(bundle->disks);
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
ffStrbufInitF(&device->devPath, "/devices%s", di_devfs_path(node));
|
||||
ffStrbufInit(&device->serial);
|
||||
ffStrbufInit(&device->revision);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
|
||||
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
device->size = 0;
|
||||
|
||||
char* buf;
|
||||
if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-serial-no", &buf) > 0)
|
||||
ffStrbufSetS(&device->serial, buf);
|
||||
if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-revision-id", &buf) > 0)
|
||||
ffStrbufSetS(&device->revision, buf);
|
||||
if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "class", &buf) > 0)
|
||||
ffStrbufSetS(&device->interconnect, buf);
|
||||
|
||||
device->type |= di_prop_find(DDI_DEV_T_ANY, node, "removable-media") ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
|
||||
int* value;
|
||||
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-solid-state", &value) > 0)
|
||||
device->type |= *value ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
|
||||
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type", &value) > 0)
|
||||
device->type |= *value == DTYPE_DIRECT ? FF_PHYSICALDISK_TYPE_READWRITE : *value == DTYPE_RODIRECT ? FF_PHYSICALDISK_TYPE_READONLY : 0;
|
||||
|
||||
int64_t* nblocks;
|
||||
if (di_prop_lookup_int64(DDI_DEV_T_ANY, node, "device-nblocks", &nblocks) > 0
|
||||
&& di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-blksize", &value) > 0)
|
||||
device->size = (uint64_t) ((uint64_t) *nblocks * (uint64_t) *value);
|
||||
}
|
||||
|
||||
return DI_WALK_CONTINUE;
|
||||
}
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
{
|
||||
di_node_t rootNode = di_init("/", DINFOCPYALL);
|
||||
if (rootNode == DI_NODE_NIL)
|
||||
return "di_init() failed";
|
||||
di_walk_minor(rootNode, DDI_NT_BLOCK, DI_WALK_CLDFIRST, &(struct FFWalkTreeBundle) { options, result }, (void*) walkDevTree);
|
||||
di_fini(rootNode);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,909 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 4Front Technologies 1996-2008.
|
||||
*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SYS_AUDIO_OSS_H
|
||||
#define _SYS_AUDIO_OSS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
* These are the ioctl calls for all Solaris /dev/dsp and /dev/mixer audio
|
||||
* devices.
|
||||
*
|
||||
* Note that the contents of this file include definitions which exist
|
||||
* primarily for compatibility. Many of the defines here are not
|
||||
* actually implemented, but exist solely to facilitate compilation of
|
||||
* programs from other operating systems. Other definitions here may
|
||||
* not be fully supported or may otherwise be obsolete. There are many
|
||||
* things in this file which should not be used on SunOS.
|
||||
*
|
||||
* Please read the documentation to determine which portions of the
|
||||
* API are fully supported and recommended for use in new
|
||||
* applications.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Buffer status queries.
|
||||
* SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE
|
||||
*/
|
||||
typedef struct audio_buf_info {
|
||||
int fragments; /* # of available fragments */
|
||||
int fragstotal; /* Total # of fragments allocated */
|
||||
int fragsize; /* Size of a fragment in bytes */
|
||||
int bytes; /* Available space in bytes */
|
||||
/* Note! 'bytes' could be more than fragments*fragsize */
|
||||
} audio_buf_info;
|
||||
|
||||
/*
|
||||
* Sync groups for audio devices.
|
||||
* SNDCTL_DSP_SYNCGROUP and SNDCTL_DSP_SYNCSTART
|
||||
*/
|
||||
typedef struct oss_syncgroup {
|
||||
int id;
|
||||
int mode;
|
||||
int filler[16];
|
||||
} oss_syncgroup;
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_GETERROR
|
||||
*/
|
||||
typedef struct audio_errinfo {
|
||||
int play_underruns;
|
||||
int rec_overruns;
|
||||
unsigned int play_ptradjust;
|
||||
unsigned int rec_ptradjust;
|
||||
int play_errorcount;
|
||||
int rec_errorcount;
|
||||
int play_lasterror;
|
||||
int rec_lasterror;
|
||||
int play_errorparm;
|
||||
int rec_errorparm;
|
||||
int filler[16];
|
||||
} audio_errinfo;
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR
|
||||
*/
|
||||
typedef struct count_info {
|
||||
unsigned int bytes; /* Total # of bytes processed */
|
||||
int blocks; /* # of fragment transitions since last time */
|
||||
int ptr; /* Current DMA pointer value */
|
||||
} count_info;
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_CURENT_IPTR and SNDCTL_DSP_CURRENT_OPTR
|
||||
*/
|
||||
typedef struct {
|
||||
long long samples; /* Total # of samples */
|
||||
int fifo_samples; /* Samples in device FIFO */
|
||||
int filler[32]; /* For future use */
|
||||
} oss_count_t;
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_GET_RECSRC_NAMES and SNDCTL_DSP_GET_PLAYTGT_NAMES
|
||||
*/
|
||||
#define OSS_ENUM_MAXVALUE 255
|
||||
typedef struct oss_mixer_enuminfo {
|
||||
int dev;
|
||||
int ctrl;
|
||||
int nvalues;
|
||||
int version;
|
||||
short strindex[OSS_ENUM_MAXVALUE];
|
||||
char strings[3000];
|
||||
} oss_mixer_enuminfo;
|
||||
|
||||
/*
|
||||
* Digital interface (S/PDIF) control interface
|
||||
* SNDCTL_DSP_READCTL and SNDCTL_DSP_WRITECTL
|
||||
*/
|
||||
typedef struct oss_digital_control {
|
||||
unsigned int caps;
|
||||
#define DIG_CBITIN_NONE 0x00000000
|
||||
#define DIG_CBITIN_LIMITED 0x00000001
|
||||
#define DIG_CBITIN_DATA 0x00000002
|
||||
#define DIG_CBITIN_BYTE0 0x00000004
|
||||
#define DIG_CBITIN_FULL 0x00000008
|
||||
#define DIG_CBITIN_MASK 0x0000000f
|
||||
#define DIG_CBITOUT_NONE 0x00000000
|
||||
#define DIG_CBITOUT_LIMITED 0x00000010
|
||||
#define DIG_CBITOUT_BYTE0 0x00000020
|
||||
#define DIG_CBITOUT_FULL 0x00000040
|
||||
#define DIG_CBITOUT_DATA 0x00000080
|
||||
#define DIG_CBITOUT_MASK 0x000000f0
|
||||
#define DIG_UBITIN 0x00000100
|
||||
#define DIG_UBITOUT 0x00000200
|
||||
#define DIG_VBITOUT 0x00000400
|
||||
#define DIG_OUTRATE 0x00000800
|
||||
#define DIG_INRATE 0x00001000
|
||||
#define DIG_INBITS 0x00002000
|
||||
#define DIG_OUTBITS 0x00004000
|
||||
#define DIG_EXACT 0x00010000
|
||||
#define DIG_PRO 0x00020000
|
||||
#define DIG_CONSUMER 0x00040000
|
||||
#define DIG_PASSTHROUGH 0x00080000
|
||||
#define DIG_OUTSEL 0x00100000
|
||||
|
||||
unsigned int valid;
|
||||
#define VAL_CBITIN 0x00000001
|
||||
#define VAL_UBITIN 0x00000002
|
||||
#define VAL_CBITOUT 0x00000004
|
||||
#define VAL_UBITOUT 0x00000008
|
||||
#define VAL_ISTATUS 0x00000010
|
||||
#define VAL_IRATE 0x00000020
|
||||
#define VAL_ORATE 0x00000040
|
||||
#define VAL_INBITS 0x00000080
|
||||
#define VAL_OUTBITS 0x00000100
|
||||
#define VAL_REQUEST 0x00000200
|
||||
#define VAL_OUTSEL 0x00000400
|
||||
|
||||
#define VAL_OUTMASK (VAL_CBITOUT|VAL_UBITOUT|VAL_ORATE|VAL_OUTBITS|VAL_OUTSEL)
|
||||
|
||||
unsigned int request;
|
||||
unsigned int param;
|
||||
#define SPD_RQ_PASSTHROUGH 1
|
||||
|
||||
unsigned char cbitin[24];
|
||||
unsigned char ubitin[24];
|
||||
unsigned char cbitout[24];
|
||||
unsigned char ubitout[24];
|
||||
|
||||
unsigned int outsel;
|
||||
#define OUTSEL_DIGITAL 1
|
||||
#define OUTSEL_ANALOG 2
|
||||
#define OUTSEL_BOTH (OUTSEL_DIGITAL|OUTSEL_ANALOG)
|
||||
|
||||
int in_data; /* Audio/data if autodetectable by receiver */
|
||||
#define IND_UNKNOWN 0
|
||||
#define IND_AUDIO 1
|
||||
#define IND_DATA 2
|
||||
|
||||
int in_locked; /* Receiver locked */
|
||||
#define LOCK_NOT_INDICATED 0
|
||||
#define LOCK_UNLOCKED 1
|
||||
#define LOCK_LOCKED 2
|
||||
|
||||
int in_quality; /* Input signal quality */
|
||||
#define IN_QUAL_NOT_INDICATED 0
|
||||
#define IN_QUAL_POOR 1
|
||||
#define IN_QUAL_GOOD 2
|
||||
|
||||
int in_vbit;
|
||||
int out_vbit; /* V bits */
|
||||
#define VBIT_NOT_INDICATED 0
|
||||
#define VBIT_OFF 1
|
||||
#define VBIT_ON 2
|
||||
|
||||
unsigned int in_errors; /* Various input error conditions */
|
||||
#define INERR_CRC 0x0001
|
||||
#define INERR_QCODE_CRC 0x0002
|
||||
#define INERR_PARITY 0x0004
|
||||
#define INERR_BIPHASE 0x0008
|
||||
|
||||
int srate_in;
|
||||
int srate_out;
|
||||
int bits_in;
|
||||
int bits_out;
|
||||
|
||||
int filler[32];
|
||||
} oss_digital_control;
|
||||
|
||||
/*
|
||||
* The "new" mixer API.
|
||||
*
|
||||
* This improved mixer API makes it possible to access every possible feature
|
||||
* of every possible device. However you should read the mixer programming
|
||||
* section of the OSS API Developer's Manual. There is no chance that you
|
||||
* could use this interface correctly just by examining this header.
|
||||
*/
|
||||
#define OSS_VERSION 0x040003
|
||||
#define SOUND_VERSION OSS_VERSION
|
||||
|
||||
typedef struct oss_sysinfo {
|
||||
char product[32]; /* E.g. SunOS Audio */
|
||||
char version[32]; /* E.g. 4.0a */
|
||||
int versionnum; /* See OSS_GETVERSION */
|
||||
char options[128]; /* NOT SUPPORTED */
|
||||
|
||||
int numaudios; /* # of audio/dsp devices */
|
||||
int openedaudio[8]; /* Mask of audio devices are busy */
|
||||
|
||||
int numsynths; /* NOT SUPPORTED, always 0 */
|
||||
int nummidis; /* NOT SUPPORTED, always 0 */
|
||||
int numtimers; /* NOT SUPPORTED, always 0 */
|
||||
int nummixers; /* # of mixer devices */
|
||||
|
||||
int openedmidi[8]; /* Mask of midi devices are busy */
|
||||
int numcards; /* Number of sound cards in the system */
|
||||
int numaudioengines; /* Number of audio engines in the system */
|
||||
char license[16]; /* E.g. "GPL" or "CDDL" */
|
||||
char revision_info[256]; /* For internal use */
|
||||
int filler[172]; /* For future expansion */
|
||||
} oss_sysinfo;
|
||||
|
||||
typedef struct oss_mixext {
|
||||
int dev; /* Mixer device number */
|
||||
int ctrl; /* Extension number */
|
||||
int type; /* Entry type */
|
||||
#define MIXT_DEVROOT 0 /* Device root entry */
|
||||
#define MIXT_GROUP 1 /* Controller group */
|
||||
#define MIXT_ONOFF 2 /* OFF (0) or ON (1) */
|
||||
#define MIXT_ENUM 3 /* Enumerated (0 to maxvalue) */
|
||||
#define MIXT_MONOSLIDER 4 /* Mono slider (0 to 255) */
|
||||
#define MIXT_STEREOSLIDER 5 /* Stereo slider (dual 0 to 255) */
|
||||
#define MIXT_MESSAGE 6 /* (Readable) textual message */
|
||||
#define MIXT_MONOVU 7 /* VU meter value (mono) */
|
||||
#define MIXT_STEREOVU 8 /* VU meter value (stereo) */
|
||||
#define MIXT_MONOPEAK 9 /* VU meter peak value (mono) */
|
||||
#define MIXT_STEREOPEAK 10 /* VU meter peak value (stereo) */
|
||||
#define MIXT_RADIOGROUP 11 /* Radio button group */
|
||||
#define MIXT_MARKER 12 /* Separator between entries */
|
||||
#define MIXT_VALUE 13 /* Decimal value entry */
|
||||
#define MIXT_HEXVALUE 14 /* Hexadecimal value entry */
|
||||
#define MIXT_MONODB 15 /* OBSOLETE */
|
||||
#define MIXT_STEREODB 16 /* OBSOLETE */
|
||||
#define MIXT_SLIDER 17 /* Slider (mono, 31 bit int range) */
|
||||
#define MIXT_3D 18
|
||||
#define MIXT_MONOSLIDER16 19 /* Mono slider (0-32767) */
|
||||
#define MIXT_STEREOSLIDER16 20 /* Stereo slider (dual 0-32767) */
|
||||
#define MIXT_MUTE 21 /* Mute=1, unmute=0 */
|
||||
|
||||
/* Possible value range (minvalue to maxvalue) */
|
||||
/* Note that maxvalue may also be smaller than minvalue */
|
||||
int maxvalue;
|
||||
int minvalue;
|
||||
|
||||
int flags;
|
||||
#define MIXF_READABLE 0x00000001 /* Has readable value */
|
||||
#define MIXF_WRITEABLE 0x00000002 /* Has writeable value */
|
||||
#define MIXF_POLL 0x00000004 /* May change itself */
|
||||
#define MIXF_HZ 0x00000008 /* Hertz scale */
|
||||
#define MIXF_STRING 0x00000010 /* Use dynamic extensions for value */
|
||||
#define MIXF_DYNAMIC 0x00000010 /* Supports dynamic extensions */
|
||||
#define MIXF_OKFAIL 0x00000020 /* Interpret value as 1=OK, 0=FAIL */
|
||||
#define MIXF_FLAT 0x00000040 /* NOT SUPPORTED */
|
||||
#define MIXF_LEGACY 0x00000080 /* NOT SUPPORTED */
|
||||
#define MIXF_CENTIBEL 0x00000100 /* Centibel (0.1 dB) step size */
|
||||
#define MIXF_DECIBEL 0x00000200 /* Step size of 1 dB */
|
||||
#define MIXF_MAINVOL 0x00000400 /* Main volume control */
|
||||
#define MIXF_PCMVOL 0x00000800 /* PCM output volume control */
|
||||
#define MIXF_RECVOL 0x00001000 /* PCM recording volume control */
|
||||
#define MIXF_MONVOL 0x00002000 /* Input->output monitor volume */
|
||||
#define MIXF_WIDE 0x00004000 /* NOT SUPPORTED */
|
||||
#define MIXF_DESCR 0x00008000 /* NOT SUPPORTED */
|
||||
#define MIXF_DISABLE 0x00010000 /* Control has been disabled */
|
||||
|
||||
char id[16]; /* Mnemonic ID (internal use) */
|
||||
int parent; /* Entry# of parent (-1 if root) */
|
||||
|
||||
int dummy; /* NOT SUPPORTED */
|
||||
|
||||
int timestamp;
|
||||
|
||||
char data[64]; /* Misc data (entry type dependent) */
|
||||
unsigned char enum_present[32]; /* Mask of allowed enum values */
|
||||
int control_no; /* NOT SUPPORTED, always -1 */
|
||||
|
||||
unsigned int desc; /* Scope flags, etc */
|
||||
#define MIXEXT_SCOPE_MASK 0x0000003f
|
||||
#define MIXEXT_SCOPE_OTHER 0x00000000
|
||||
#define MIXEXT_SCOPE_INPUT 0x00000001
|
||||
#define MIXEXT_SCOPE_OUTPUT 0x00000002
|
||||
#define MIXEXT_SCOPE_MONITOR 0x00000003
|
||||
#define MIXEXT_SCOPE_RECSWITCH 0x00000004
|
||||
|
||||
char extname[32];
|
||||
int update_counter;
|
||||
#ifdef _KERNEL
|
||||
int filler[6];
|
||||
int enumbit;
|
||||
#else
|
||||
int filler[7];
|
||||
#endif
|
||||
} oss_mixext;
|
||||
|
||||
typedef struct oss_mixext_root {
|
||||
char id[16];
|
||||
char name[48];
|
||||
} oss_mixext_root;
|
||||
|
||||
typedef struct oss_mixer_value {
|
||||
int dev;
|
||||
int ctrl;
|
||||
int value;
|
||||
int flags; /* Reserved for future use. Initialize to 0 */
|
||||
int timestamp; /* Must be set to oss_mixext.timestamp */
|
||||
int filler[8]; /* Reserved for future use. Initialize to 0 */
|
||||
} oss_mixer_value;
|
||||
|
||||
#define OSS_LONGNAME_SIZE 64
|
||||
#define OSS_LABEL_SIZE 16
|
||||
#define OSS_DEVNODE_SIZE 32
|
||||
typedef char oss_longname_t[OSS_LONGNAME_SIZE];
|
||||
typedef char oss_label_t[OSS_LABEL_SIZE];
|
||||
typedef char oss_devnode_t[OSS_DEVNODE_SIZE];
|
||||
|
||||
|
||||
typedef struct oss_audioinfo {
|
||||
int dev; /* Audio device number */
|
||||
char name[64];
|
||||
int busy; /* 0, OPEN_READ, OPEN_WRITE, OPEN_READWRITE */
|
||||
int pid; /* Process ID, not used in SunOS */
|
||||
int caps; /* PCM_CAP_INPUT, PCM_CAP_OUTPUT */
|
||||
int iformats; /* Supported input formats */
|
||||
int oformats; /* Supported output formats */
|
||||
int magic; /* Internal use only */
|
||||
char cmd[64]; /* Command using the device (if known) */
|
||||
int card_number;
|
||||
int port_number;
|
||||
int mixer_dev;
|
||||
int legacy_device; /* Obsolete field. Replaced by devnode */
|
||||
int enabled; /* 1=enabled, 0=device not ready */
|
||||
int flags; /* internal use only - no practical meaning */
|
||||
int min_rate; /* Minimum sample rate */
|
||||
int max_rate; /* Maximum sample rate */
|
||||
int min_channels; /* Minimum number of channels */
|
||||
int max_channels; /* Maximum number of channels */
|
||||
int binding; /* DSP_BIND_FRONT, etc. 0 means undefined */
|
||||
int rate_source;
|
||||
char handle[32];
|
||||
#define OSS_MAX_SAMPLE_RATES 20 /* Cannot be changed */
|
||||
unsigned int nrates; /* Array of supported sample rates */
|
||||
unsigned int rates[OSS_MAX_SAMPLE_RATES];
|
||||
oss_longname_t song_name; /* Song name (if given) */
|
||||
oss_label_t label; /* Device label (if given) */
|
||||
int latency; /* In usecs, -1=unknown */
|
||||
oss_devnode_t devnode; /* Device special file name (absolute path) */
|
||||
int next_play_engine;
|
||||
int next_rec_engine;
|
||||
int filler[184];
|
||||
} oss_audioinfo;
|
||||
|
||||
typedef struct oss_mixerinfo {
|
||||
int dev;
|
||||
char id[16];
|
||||
char name[32];
|
||||
int modify_counter;
|
||||
int card_number;
|
||||
int port_number;
|
||||
char handle[32];
|
||||
int magic; /* Reserved */
|
||||
int enabled; /* Reserved */
|
||||
int caps;
|
||||
#define MIXER_CAP_VIRTUAL 0x00000001
|
||||
#define MIXER_CAP_LAYOUT_B 0x00000002 /* For internal use only */
|
||||
#define MIXER_CAP_NARROW 0x00000004 /* Conserve horiz space */
|
||||
int flags; /* Reserved */
|
||||
int nrext;
|
||||
/*
|
||||
* The priority field can be used to select the default
|
||||
* (motherboard) mixer device. The mixer with the highest
|
||||
* priority is the most preferred one. -2 or less means that
|
||||
* this device cannot be used as the default mixer.
|
||||
*/
|
||||
int priority;
|
||||
oss_devnode_t devnode; /* Device special file name (absolute path) */
|
||||
int legacy_device;
|
||||
int filler[245]; /* Reserved */
|
||||
} oss_mixerinfo;
|
||||
|
||||
typedef struct oss_card_info {
|
||||
int card;
|
||||
char shortname[16];
|
||||
char longname[128];
|
||||
int flags;
|
||||
char hw_info[400];
|
||||
int intr_count;
|
||||
int ack_count;
|
||||
int filler[154];
|
||||
} oss_card_info;
|
||||
|
||||
typedef struct mixer_info { /* OBSOLETE */
|
||||
char id[16];
|
||||
char name[32];
|
||||
int modify_counter;
|
||||
int card_number;
|
||||
int port_number;
|
||||
char handle[32];
|
||||
} mixer_info;
|
||||
|
||||
#define MAX_PEAK_CHANNELS 128
|
||||
typedef unsigned short oss_peaks_t[MAX_PEAK_CHANNELS];
|
||||
|
||||
/* For use with SNDCTL_DSP_GET_CHNORDER */
|
||||
#define CHID_UNDEF 0
|
||||
#define CHID_L 1
|
||||
#define CHID_R 2
|
||||
#define CHID_C 3
|
||||
#define CHID_LFE 4
|
||||
#define CHID_LS 5
|
||||
#define CHID_RS 6
|
||||
#define CHID_LR 7
|
||||
#define CHID_RR 8
|
||||
#define CHNORDER_UNDEF 0x0000000000000000ULL
|
||||
#define CHNORDER_NORMAL 0x0000000087654321ULL
|
||||
|
||||
|
||||
#define OSSIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */
|
||||
#define OSSIOC_VOID 0x00000000 /* no parameters */
|
||||
#define OSSIOC_OUT 0x20000000 /* copy out parameters */
|
||||
#define OSSIOC_IN 0x40000000 /* copy in parameters */
|
||||
#define OSSIOC_INOUT (OSSIOC_IN|OSSIOC_OUT)
|
||||
#define OSSIOC_SZ(t) ((sizeof (t) & OSSIOCPARM_MASK) << 16)
|
||||
#define OSSIOC_GETSZ(x) (((x) >> 16) & OSSIOCPARM_MASK)
|
||||
|
||||
#define __OSSIO(x, y) ((int)(OSSIOC_VOID|(x<<8)|y))
|
||||
#define __OSSIOR(x, y, t) ((int)(OSSIOC_OUT|OSSIOC_SZ(t)|(x<<8)|y))
|
||||
#define __OSSIOW(x, y, t) ((int)(OSSIOC_IN|OSSIOC_SZ(t)|(x<<8)|y))
|
||||
#define __OSSIOWR(x, y, t) ((int)(OSSIOC_INOUT|OSSIOC_SZ(t)|(x<<8)|y))
|
||||
|
||||
#define SNDCTL_SYSINFO __OSSIOR('X', 1, oss_sysinfo)
|
||||
#define OSS_SYSINFO SNDCTL_SYSINFO /* Old name */
|
||||
|
||||
#define SNDCTL_MIX_NRMIX __OSSIOR('X', 2, int)
|
||||
#define SNDCTL_MIX_NREXT __OSSIOWR('X', 3, int)
|
||||
#define SNDCTL_MIX_EXTINFO __OSSIOWR('X', 4, oss_mixext)
|
||||
#define SNDCTL_MIX_READ __OSSIOWR('X', 5, oss_mixer_value)
|
||||
#define SNDCTL_MIX_WRITE __OSSIOWR('X', 6, oss_mixer_value)
|
||||
|
||||
#define SNDCTL_AUDIOINFO __OSSIOWR('X', 7, oss_audioinfo)
|
||||
#define SNDCTL_MIX_ENUMINFO __OSSIOWR('X', 8, oss_mixer_enuminfo)
|
||||
#define SNDCTL_MIDIINFO __OSSIO('X', 9)
|
||||
#define SNDCTL_MIXERINFO __OSSIOWR('X', 10, oss_mixerinfo)
|
||||
#define SNDCTL_CARDINFO __OSSIOWR('X', 11, oss_card_info)
|
||||
#define SNDCTL_ENGINEINFO __OSSIOWR('X', 12, oss_audioinfo)
|
||||
#define SNDCTL_AUDIOINFO_EX __OSSIOWR('X', 13, oss_audioinfo)
|
||||
#define SNDCTL_MIX_DESCRIPTION __OSSIOWR('X', 14, oss_mixer_enuminfo)
|
||||
|
||||
/* ioctl codes 'X', 200-255 are reserved for internal use */
|
||||
|
||||
/*
|
||||
* Few more "globally" available ioctl calls.
|
||||
*/
|
||||
#define SNDCTL_SETSONG __OSSIOW('Y', 2, oss_longname_t)
|
||||
#define SNDCTL_GETSONG __OSSIOR('Y', 2, oss_longname_t)
|
||||
#define SNDCTL_SETNAME __OSSIOW('Y', 3, oss_longname_t)
|
||||
#define SNDCTL_SETLABEL __OSSIOW('Y', 4, oss_label_t)
|
||||
#define SNDCTL_GETLABEL __OSSIOR('Y', 4, oss_label_t)
|
||||
|
||||
/*
|
||||
* IOCTL commands for /dev/dsp
|
||||
*/
|
||||
#define SNDCTL_DSP_HALT __OSSIO('P', 0)
|
||||
#define SNDCTL_DSP_RESET SNDCTL_DSP_HALT /* Old name */
|
||||
#define SNDCTL_DSP_SYNC __OSSIO('P', 1)
|
||||
#define SNDCTL_DSP_SPEED __OSSIOWR('P', 2, int)
|
||||
|
||||
#define SNDCTL_DSP_STEREO __OSSIOWR('P', 3, int) /* OBSOLETE */
|
||||
|
||||
#define SNDCTL_DSP_GETBLKSIZE __OSSIOWR('P', 4, int)
|
||||
#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
|
||||
#define SNDCTL_DSP_CHANNELS __OSSIOWR('P', 6, int)
|
||||
#define SNDCTL_DSP_POST __OSSIO('P', 8)
|
||||
#define SNDCTL_DSP_SUBDIVIDE __OSSIOWR('P', 9, int)
|
||||
#define SNDCTL_DSP_SETFRAGMENT __OSSIOWR('P', 10, int)
|
||||
|
||||
#define SNDCTL_DSP_GETFMTS __OSSIOR('P', 11, int) /* Returns a mask */
|
||||
#define SNDCTL_DSP_SETFMT __OSSIOWR('P', 5, int) /* Selects ONE fmt */
|
||||
|
||||
#define SNDCTL_DSP_GETOSPACE __OSSIOR('P', 12, audio_buf_info)
|
||||
#define SNDCTL_DSP_GETISPACE __OSSIOR('P', 13, audio_buf_info)
|
||||
#define SNDCTL_DSP_NONBLOCK __OSSIO('P', 14) /* Obsolete */
|
||||
#define SNDCTL_DSP_GETCAPS __OSSIOR('P', 15, int)
|
||||
|
||||
#define SNDCTL_DSP_GETTRIGGER __OSSIOR('P', 16, int)
|
||||
#define SNDCTL_DSP_SETTRIGGER __OSSIOW('P', 16, int)
|
||||
|
||||
#define SNDCTL_DSP_GETIPTR __OSSIOR('P', 17, count_info)
|
||||
#define SNDCTL_DSP_GETOPTR __OSSIOR('P', 18, count_info)
|
||||
|
||||
#define SNDCTL_DSP_SETSYNCRO __OSSIO('P', 21)
|
||||
#define SNDCTL_DSP_SETDUPLEX __OSSIO('P', 22)
|
||||
|
||||
#define SNDCTL_DSP_PROFILE __OSSIOW('P', 23, int) /* OBSOLETE */
|
||||
#define APF_NORMAL 0 /* Normal applications */
|
||||
#define APF_NETWORK 1 /* Underruns caused by "external" delay */
|
||||
#define APF_CPUINTENS 2 /* Underruns caused by "overheating" the CPU */
|
||||
|
||||
|
||||
#define SNDCTL_DSP_GETODELAY __OSSIOR('P', 23, int)
|
||||
|
||||
#define SNDCTL_DSP_GETPLAYVOL __OSSIOR('P', 24, int)
|
||||
#define SNDCTL_DSP_SETPLAYVOL __OSSIOWR('P', 24, int)
|
||||
#define SNDCTL_DSP_GETERROR __OSSIOR('P', 25, audio_errinfo)
|
||||
|
||||
#define SNDCTL_DSP_READCTL __OSSIOWR('P', 26, oss_digital_control)
|
||||
#define SNDCTL_DSP_WRITECTL __OSSIOWR('P', 27, oss_digital_control)
|
||||
|
||||
#define SNDCTL_DSP_SYNCGROUP __OSSIOWR('P', 28, oss_syncgroup)
|
||||
#define SNDCTL_DSP_SYNCSTART __OSSIOW('P', 29, int)
|
||||
|
||||
#define SNDCTL_DSP_COOKEDMODE __OSSIOW('P', 30, int)
|
||||
|
||||
#define SNDCTL_DSP_SILENCE __OSSIO('P', 31)
|
||||
#define SNDCTL_DSP_SKIP __OSSIO('P', 32)
|
||||
|
||||
#define SNDCTL_DSP_HALT_INPUT __OSSIO('P', 33)
|
||||
#define SNDCTL_DSP_RESET_INPUT SNDCTL_DSP_HALT_INPUT /* Old name */
|
||||
#define SNDCTL_DSP_HALT_OUTPUT __OSSIO('P', 34)
|
||||
#define SNDCTL_DSP_RESET_OUTPUT SNDCTL_DSP_HALT_OUTPUT /* Old name */
|
||||
|
||||
#define SNDCTL_DSP_LOW_WATER __OSSIOW('P', 34, int)
|
||||
|
||||
#define SNDCTL_DSP_CURRENT_IPTR __OSSIOR('P', 35, oss_count_t)
|
||||
#define SNDCTL_DSP_CURRENT_OPTR __OSSIOR('P', 36, oss_count_t)
|
||||
|
||||
#define SNDCTL_DSP_GET_RECSRC_NAMES __OSSIOR('P', 37, oss_mixer_enuminfo)
|
||||
#define SNDCTL_DSP_GET_RECSRC __OSSIOR('P', 38, int)
|
||||
#define SNDCTL_DSP_SET_RECSRC __OSSIOWR('P', 38, int)
|
||||
|
||||
#define SNDCTL_DSP_GET_PLAYTGT_NAMES __OSSIOR('P', 39, oss_mixer_enuminfo)
|
||||
#define SNDCTL_DSP_GET_PLAYTGT __OSSIOR('P', 40, int)
|
||||
#define SNDCTL_DSP_SET_PLAYTGT __OSSIOWR('P', 40, int)
|
||||
#define SNDCTL_DSP_GETRECVOL __OSSIOR('P', 41, int)
|
||||
#define SNDCTL_DSP_SETRECVOL __OSSIOWR('P', 41, int)
|
||||
|
||||
#define SNDCTL_DSP_GET_CHNORDER __OSSIOR('P', 42, unsigned long long)
|
||||
#define SNDCTL_DSP_SET_CHNORDER __OSSIOWR('P', 42, unsigned long long)
|
||||
|
||||
#define SNDCTL_DSP_GETIPEAKS __OSSIOR('P', 43, oss_peaks_t)
|
||||
#define SNDCTL_DSP_GETOPEAKS __OSSIOR('P', 44, oss_peaks_t)
|
||||
|
||||
#define SNDCTL_DSP_POLICY __OSSIOW('P', 45, int) /* See the manual */
|
||||
|
||||
#define SNDCTL_DSP_GETCHANNELMASK __OSSIOWR('P', 64, int)
|
||||
#define SNDCTL_DSP_BIND_CHANNEL __OSSIOWR('P', 65, int)
|
||||
|
||||
/*
|
||||
* These definitions are here for the benefit of compiling application
|
||||
* code. Most of these are NOT implemented in the Solaris code,
|
||||
* however. This is the older 3.x OSS API, and only the master input and
|
||||
* output levels are actually supported.
|
||||
*/
|
||||
#define SOUND_MIXER_NRDEVICES 28
|
||||
#define SOUND_MIXER_VOLUME 0
|
||||
#define SOUND_MIXER_BASS 1
|
||||
#define SOUND_MIXER_TREBLE 2
|
||||
#define SOUND_MIXER_SYNTH 3
|
||||
#define SOUND_MIXER_PCM 4
|
||||
#define SOUND_MIXER_SPEAKER 5
|
||||
#define SOUND_MIXER_LINE 6
|
||||
#define SOUND_MIXER_MIC 7
|
||||
#define SOUND_MIXER_CD 8
|
||||
#define SOUND_MIXER_IMIX 9 /* Recording monitor */
|
||||
#define SOUND_MIXER_ALTPCM 10
|
||||
#define SOUND_MIXER_RECLEV 11 /* Recording level */
|
||||
#define SOUND_MIXER_IGAIN 12 /* Input gain */
|
||||
#define SOUND_MIXER_OGAIN 13 /* Output gain */
|
||||
#define SOUND_MIXER_LINE1 14 /* Input source 1 (aux1) */
|
||||
#define SOUND_MIXER_LINE2 15 /* Input source 2 (aux2) */
|
||||
#define SOUND_MIXER_LINE3 16 /* Input source 3 (line) */
|
||||
#define SOUND_MIXER_DIGITAL1 17 /* Digital I/O 1 */
|
||||
#define SOUND_MIXER_DIGITAL2 18 /* Digital I/O 2 */
|
||||
#define SOUND_MIXER_DIGITAL3 19 /* Digital I/O 3 */
|
||||
#define SOUND_MIXER_PHONE 20 /* Phone */
|
||||
#define SOUND_MIXER_MONO 21 /* Mono Output */
|
||||
#define SOUND_MIXER_VIDEO 22 /* Video/TV (audio) in */
|
||||
#define SOUND_MIXER_RADIO 23 /* Radio in */
|
||||
#define SOUND_MIXER_DEPTH 24 /* Surround depth */
|
||||
#define SOUND_MIXER_REARVOL 25 /* Rear/Surround speaker vol */
|
||||
#define SOUND_MIXER_CENTERVOL 26 /* Center/LFE speaker vol */
|
||||
#define SOUND_MIXER_SIDEVOL 27 /* Side-Surround (8speaker) vol */
|
||||
#define SOUND_MIXER_SURRVOL SOUND_MIXER_SIDEVOL
|
||||
#define SOUND_ONOFF_MIN 28
|
||||
#define SOUND_ONOFF_MAX 30
|
||||
#define SOUND_MIXER_NONE 31
|
||||
|
||||
#define SOUND_MIXER_RECSRC 0xff /* Recording sources */
|
||||
#define SOUND_MIXER_DEVMASK 0xfe /* Supported devices */
|
||||
#define SOUND_MIXER_RECMASK 0xfd /* Recording sources */
|
||||
#define SOUND_MIXER_CAPS 0xfc /* Mixer capabilities (do not use) */
|
||||
#define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
|
||||
#define SOUND_MIXER_OUTSRC 0xfa
|
||||
#define SOUND_MIXER_OUTMASK 0xf9
|
||||
|
||||
#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE
|
||||
#define SOUND_MIXER_MUTE SOUND_MIXER_NONE
|
||||
#define SOUND_MIXER_LOUD SOUND_MIXER_NONE
|
||||
|
||||
#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME)
|
||||
#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS)
|
||||
#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE)
|
||||
#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH)
|
||||
#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM)
|
||||
#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER)
|
||||
#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE)
|
||||
#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC)
|
||||
#define SOUND_MASK_CD (1 << SOUND_MIXER_CD)
|
||||
#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX)
|
||||
#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM)
|
||||
#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV)
|
||||
#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN)
|
||||
#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN)
|
||||
#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1)
|
||||
#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2)
|
||||
#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3)
|
||||
#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1)
|
||||
#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2)
|
||||
#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3)
|
||||
#define SOUND_MASK_MONO (1 << SOUND_MIXER_MONO)
|
||||
#define SOUND_MASK_PHONE (1 << SOUND_MIXER_PHONE)
|
||||
#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO)
|
||||
#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO)
|
||||
#define SOUND_MASK_DEPTH (1 << SOUND_MIXER_DEPTH)
|
||||
#define SOUND_MASK_REARVOL (1 << SOUND_MIXER_REARVOL)
|
||||
#define SOUND_MASK_CENTERVOL (1 << SOUND_MIXER_CENTERVOL)
|
||||
#define SOUND_MASK_SIDEVOL (1 << SOUND_MIXER_SIDEVOL)
|
||||
#define SOUND_MASK_SURRVOL SOUND_MASK_SIDEVOL
|
||||
#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
|
||||
#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
|
||||
#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
|
||||
|
||||
/*
|
||||
* Again, DO NOT USE the following two macros. They are here for SOURCE
|
||||
* COMPATIBILITY ONLY.
|
||||
*/
|
||||
#define SOUND_DEVICE_LABELS { \
|
||||
"Vol ", "Bass ", "Treble", "Synth", "Pcm ", "Speaker ", "Line ", \
|
||||
"Mic ", "CD ", "Mix ", "Pcm2 ", "Rec ", "IGain", "OGain", \
|
||||
"Aux1", "Aux2", "Aux3", "Digital1", "Digital2", "Digital3", \
|
||||
"Phone", "Mono", "Video", "Radio", "Depth", \
|
||||
"Rear", "Center", "Side" }
|
||||
|
||||
#define SOUND_DEVICE_NAMES { \
|
||||
"vol", "bass", "treble", "synth", "pcm", "speaker", "line", \
|
||||
"mic", "cd", "mix", "pcm2", "rec", "igain", "ogain", \
|
||||
"aux1", "aux2", "aux3", "dig1", "dig2", "dig3", \
|
||||
"phone", "mono", "video", "radio", "depth", \
|
||||
"rear", "center", "side" }
|
||||
|
||||
#define MIXER_READ(dev) __OSSIOR('M', dev, int)
|
||||
#define MIXER_WRITE(dev) __OSSIOWR('M', dev, int)
|
||||
#define SOUND_MIXER_INFO __OSSIOR('M', 101, mixer_info)
|
||||
#define OSS_GETVERSION __OSSIOR('M', 118, int)
|
||||
|
||||
/*
|
||||
* These macros are useful for some applications. They are implemented
|
||||
* as soft values for the application, and do not affect real hardware.
|
||||
*/
|
||||
#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
|
||||
#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN)
|
||||
#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM)
|
||||
#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN)
|
||||
#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV)
|
||||
#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
|
||||
#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
|
||||
#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
|
||||
#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
|
||||
#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
|
||||
#define SOUND_MIXER_READ_RECGAIN __OSSIOR('M', 119, int)
|
||||
#define SOUND_MIXER_READ_MONGAIN __OSSIOR('M', 120, int)
|
||||
|
||||
#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
|
||||
#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN)
|
||||
#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM)
|
||||
#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN)
|
||||
#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV)
|
||||
#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
|
||||
#define SOUND_MIXER_WRITE_RECGAIN __OSSIOWR('M', 119, int)
|
||||
#define SOUND_MIXER_WRITE_MONGAIN __OSSIOWR('M', 120, int)
|
||||
|
||||
/*
|
||||
* These macros are here for source compatibility. They intentionally don't
|
||||
* map to any real hardware. NOT SUPPORTED!
|
||||
*/
|
||||
#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS)
|
||||
#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE)
|
||||
#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH)
|
||||
#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER)
|
||||
#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE)
|
||||
#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC)
|
||||
#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD)
|
||||
#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX)
|
||||
#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM)
|
||||
#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1)
|
||||
#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2)
|
||||
#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3)
|
||||
|
||||
#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS)
|
||||
#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE)
|
||||
#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH)
|
||||
#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER)
|
||||
#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE)
|
||||
#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC)
|
||||
#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD)
|
||||
#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX)
|
||||
#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM)
|
||||
#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1)
|
||||
#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2)
|
||||
#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3)
|
||||
|
||||
/*
|
||||
* Audio encoding types (Note! U8=8 and S16_LE=16 for compatibility)
|
||||
*/
|
||||
#define AFMT_QUERY 0x00000000 /* Return current fmt */
|
||||
#define AFMT_MU_LAW 0x00000001
|
||||
#define AFMT_A_LAW 0x00000002
|
||||
#define AFMT_IMA_ADPCM 0x00000004
|
||||
#define AFMT_U8 0x00000008
|
||||
#define AFMT_S16_LE 0x00000010
|
||||
#define AFMT_S16_BE 0x00000020
|
||||
#define AFMT_S8 0x00000040
|
||||
#define AFMT_U16_LE 0x00000080
|
||||
#define AFMT_U16_BE 0x00000100
|
||||
#define AFMT_MPEG 0x00000200 /* NOT SUPPORTED: MPEG (2) audio */
|
||||
#define AFMT_AC3 0x00000400 /* NOT SUPPORTED: AC3 compressed */
|
||||
#define AFMT_VORBIS 0x00000800 /* NOT SUPPORTED: Ogg Vorbis */
|
||||
#define AFMT_S32_LE 0x00001000
|
||||
#define AFMT_S32_BE 0x00002000
|
||||
#define AFMT_FLOAT 0x00004000 /* NOT SUPPORTED: IEEE double float */
|
||||
#define AFMT_S24_LE 0x00008000 /* LSB aligned in 32 bit word */
|
||||
#define AFMT_S24_BE 0x00010000 /* LSB aligned in 32 bit word */
|
||||
#define AFMT_SPDIF_RAW 0x00020000 /* NOT SUPPORTED: Raw S/PDIF frames */
|
||||
#define AFMT_S24_PACKED 0x00040000 /* 24 bit packed little endian */
|
||||
/*
|
||||
* Some big endian/little endian handling macros (native endian and
|
||||
* opposite endian formats).
|
||||
*/
|
||||
#if defined(_BIG_ENDIAN)
|
||||
#define AFMT_S16_NE AFMT_S16_BE
|
||||
#define AFMT_U16_NE AFMT_U16_BE
|
||||
#define AFMT_S32_NE AFMT_S32_BE
|
||||
#define AFMT_S24_NE AFMT_S24_BE
|
||||
#define AFMT_S16_OE AFMT_S16_LE
|
||||
#define AFMT_S32_OE AFMT_S32_LE
|
||||
#define AFMT_S24_OE AFMT_S24_LE
|
||||
#else
|
||||
#define AFMT_S16_NE AFMT_S16_LE
|
||||
#define AFMT_U16_NE AFMT_U16_LE
|
||||
#define AFMT_S32_NE AFMT_S32_LE
|
||||
#define AFMT_S24_NE AFMT_S24_LE
|
||||
#define AFMT_S16_OE AFMT_S16_BE
|
||||
#define AFMT_S32_OE AFMT_S32_BE
|
||||
#define AFMT_S24_OE AFMT_S24_BE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_GETCAPS bits
|
||||
*/
|
||||
#define PCM_CAP_REVISION 0x000000ff /* Revision level (0 to 255) */
|
||||
#define PCM_CAP_DUPLEX 0x00000100 /* Full duplex rec/play */
|
||||
#define PCM_CAP_REALTIME 0x00000200 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_BATCH 0x00000400 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_COPROC 0x00000800 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_TRIGGER 0x00001000 /* Supports SETTRIGGER */
|
||||
#define PCM_CAP_MMAP 0x00002000 /* Supports mmap() */
|
||||
#define PCM_CAP_MULTI 0x00004000 /* Supports multiple open */
|
||||
#define PCM_CAP_BIND 0x00008000 /* Supports channel binding */
|
||||
#define PCM_CAP_INPUT 0x00010000 /* Supports recording */
|
||||
#define PCM_CAP_OUTPUT 0x00020000 /* Supports playback */
|
||||
#define PCM_CAP_VIRTUAL 0x00040000 /* Virtual device */
|
||||
#define PCM_CAP_ANALOGOUT 0x00100000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_ANALOGIN 0x00200000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_DIGITALOUT 0x00400000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_DIGITALIN 0x00800000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_ADMASK 0x00f00000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_SHADOW 0x01000000 /* "Shadow" device */
|
||||
#define PCM_CAP_CH_MASK 0x06000000 /* See DSP_CH_MASK below */
|
||||
#define PCM_CAP_HIDDEN 0x08000000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_FREERATE 0x10000000
|
||||
#define PCM_CAP_MODEM 0x20000000 /* NOT SUPPORTED */
|
||||
#define PCM_CAP_DEFAULT 0x40000000 /* "Default" device */
|
||||
|
||||
/*
|
||||
* Preferred channel usage. These bits can be used to give
|
||||
* recommendations to the application. Used by few drivers. For
|
||||
* example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that the
|
||||
* device works best in mono mode. However it doesn't necessarily mean
|
||||
* that the device cannot be used in stereo. These bits should only be
|
||||
* used by special applications such as multi track hard disk
|
||||
* recorders to find out the initial setup. However the user should be
|
||||
* able to override this selection.
|
||||
*
|
||||
* To find out which modes are actually supported the application
|
||||
* should try to select them using SNDCTL_DSP_CHANNELS.
|
||||
*/
|
||||
#define DSP_CH_MASK 0x06000000 /* Mask */
|
||||
#define DSP_CH_ANY 0x00000000 /* No preferred mode */
|
||||
#define DSP_CH_MONO 0x02000000
|
||||
#define DSP_CH_STEREO 0x04000000
|
||||
#define DSP_CH_MULTI 0x06000000 /* More than two channels */
|
||||
|
||||
|
||||
/*
|
||||
* The PCM_CAP_* capability names used to be known as DSP_CAP_*, so
|
||||
* it's necessary to define the older names too.
|
||||
*/
|
||||
#define DSP_CAP_ADMASK PCM_CAP_ADMASK
|
||||
#define DSP_CAP_ANALOGIN PCM_CAP_ANALOGIN
|
||||
#define DSP_CAP_ANALOGOUT PCM_CAP_ANALOGOUT
|
||||
#define DSP_CAP_BATCH PCM_CAP_BATCH
|
||||
#define DSP_CAP_BIND PCM_CAP_BIND
|
||||
#define DSP_CAP_COPROC PCM_CAP_COPROC
|
||||
#define DSP_CAP_DEFAULT PCM_CAP_DEFAULT
|
||||
#define DSP_CAP_DIGITALIN PCM_CAP_DIGITALIN
|
||||
#define DSP_CAP_DIGITALOUT PCM_CAP_DIGITALOUT
|
||||
#define DSP_CAP_DUPLEX PCM_CAP_DUPLEX
|
||||
#define DSP_CAP_FREERATE PCM_CAP_FREERATE
|
||||
#define DSP_CAP_HIDDEN PCM_CAP_HIDDEN
|
||||
#define DSP_CAP_INPUT PCM_CAP_INPUT
|
||||
#define DSP_CAP_MMAP PCM_CAP_MMAP
|
||||
#define DSP_CAP_MODEM PCM_CAP_MODEM
|
||||
#define DSP_CAP_MULTI PCM_CAP_MULTI
|
||||
#define DSP_CAP_OUTPUT PCM_CAP_OUTPUT
|
||||
#define DSP_CAP_REALTIME PCM_CAP_REALTIME
|
||||
#define DSP_CAP_REVISION PCM_CAP_REVISION
|
||||
#define DSP_CAP_SHADOW PCM_CAP_SHADOW
|
||||
#define DSP_CAP_TRIGGER PCM_CAP_TRIGGER
|
||||
#define DSP_CAP_VIRTUAL PCM_CAP_VIRTUAL
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_GETTRIGGER and SNDCTL_DSP_SETTRIGGER
|
||||
*/
|
||||
#define PCM_ENABLE_INPUT 0x00000001
|
||||
#define PCM_ENABLE_OUTPUT 0x00000002
|
||||
|
||||
/*
|
||||
* SNDCTL_DSP_BIND_CHANNEL
|
||||
*/
|
||||
#define DSP_BIND_QUERY 0x00000000
|
||||
#define DSP_BIND_FRONT 0x00000001
|
||||
#define DSP_BIND_SURR 0x00000002
|
||||
#define DSP_BIND_CENTER_LFE 0x00000004
|
||||
#define DSP_BIND_HANDSET 0x00000008
|
||||
#define DSP_BIND_MIC 0x00000010
|
||||
#define DSP_BIND_MODEM1 0x00000020
|
||||
#define DSP_BIND_MODEM2 0x00000040
|
||||
#define DSP_BIND_I2S 0x00000080
|
||||
#define DSP_BIND_SPDIF 0x00000100
|
||||
#define DSP_BIND_REAR 0x00000200
|
||||
|
||||
/*
|
||||
* SOUND_MIXER_READ_CAPS
|
||||
*/
|
||||
#define SOUND_CAP_EXCL_INPUT 0x00000001
|
||||
#define SOUND_CAP_NOLEGACY 0x00000004
|
||||
#define SOUND_CAP_NORECSRC 0x00000008
|
||||
|
||||
/*
|
||||
* The following ioctl is for internal use only -- it is used to
|
||||
* coordinate /dev/sndstat numbering with file names in /dev/sound.
|
||||
* Applications must not use it. (This is duplicated in sys/audioio.h
|
||||
* as well.)
|
||||
*/
|
||||
#define SNDCTL_SUN_SEND_NUMBER __OSSIOW('X', 200, int)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_AUDIO_OSS_H */
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "sound.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#if __has_include(<sys/soundcard.h>)
|
||||
#include <sys/soundcard.h>
|
||||
#else
|
||||
// Strangely, they don't provide this file on default installation
|
||||
#include "audio_oss_sunos.h"
|
||||
#endif
|
||||
|
||||
const char* ffDetectSound(FFlist* devices)
|
||||
{
|
||||
int defaultDev;
|
||||
{
|
||||
char mixerp[12];
|
||||
ssize_t plen = readlink("/dev/audio", mixerp, ARRAY_SIZE(mixerp));
|
||||
if (plen < 6)
|
||||
return "readlink(/dev/audio) failed";
|
||||
defaultDev = mixerp[plen - 1] - '0';
|
||||
if (defaultDev < 0 || defaultDev > 9)
|
||||
return "Invalid mixer device";
|
||||
}
|
||||
|
||||
char path[] = "/dev/mixer0";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY sndstat = ffStrbufCreate();
|
||||
|
||||
struct oss_sysinfo info = { .nummixers = 9 };
|
||||
|
||||
// The implementation is very different from *BSD's. They call it OSS4
|
||||
for (int idev = 0; idev < info.nummixers; ++idev)
|
||||
{
|
||||
path[strlen("/dev/mixer")] = (char) ('0' + idev);
|
||||
FF_AUTO_CLOSE_FD int fd = open(path, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) break;
|
||||
|
||||
if (idev == 0)
|
||||
{
|
||||
if (ioctl(fd, SNDCTL_SYSINFO, &info) != 0)
|
||||
return "ioctl(SNDCTL_SYSINFO) failed";
|
||||
if (ffAppendFDBuffer(fd, &sndstat))
|
||||
ffStrbufSubstrAfterFirstS(&sndstat, "\nMixers:");
|
||||
}
|
||||
|
||||
struct oss_mixerinfo mi = {};
|
||||
if (ioctl(fd, SNDCTL_MIXERINFO, &mi) < 0)
|
||||
continue;
|
||||
|
||||
int volume = -1;
|
||||
for (int iext = 0; iext < mi.nrext; ++iext)
|
||||
{
|
||||
struct oss_mixext me = { .dev = mi.dev, .ctrl = iext };
|
||||
if (ioctl(fd, SNDCTL_MIX_EXTINFO, &me) < 0)
|
||||
continue;
|
||||
if (me.flags & MIXF_PCMVOL)
|
||||
{
|
||||
struct oss_mixer_value mv = { .dev = mi.dev, .ctrl = iext, .timestamp = me.timestamp };
|
||||
if (ioctl(fd, SNDCTL_MIX_READ, &mv) >= 0)
|
||||
{
|
||||
mv.value -= me.minvalue;
|
||||
me.maxvalue -= me.minvalue;
|
||||
volume = (uint8_t) ((mv.value * 100 + me.maxvalue / 2) / me.maxvalue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (volume == -1) continue;
|
||||
|
||||
FFSoundDevice* device = ffListAdd(devices);
|
||||
ffStrbufInitS(&device->identifier, path);
|
||||
char buf[16];
|
||||
int bufLen = snprintf(buf, ARRAY_SIZE(buf), "\n%d: ", mi.dev);
|
||||
assert(bufLen > 3);
|
||||
const char* pLine = memmem(sndstat.chars, sndstat.length, buf, (size_t) bufLen);
|
||||
if (pLine)
|
||||
{
|
||||
pLine += bufLen;
|
||||
const char* pEnd = strchr(pLine, '\n');
|
||||
if (!pEnd) pEnd = sndstat.chars + sndstat.length;
|
||||
ffStrbufInitNS(&device->name, (uint32_t) (pEnd - pLine), pLine);
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&device->name, mi.name);
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
ffStrbufInitF(&device->platformApi, "%s %s", info.product, info.version);
|
||||
device->volume = (uint8_t) volume;
|
||||
device->active = !!mi.enabled;
|
||||
device->main = defaultDev == idev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -109,6 +109,8 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
|
||||
ffStrbufEqualS(&result->processName, "chezmoi") || // #762
|
||||
ffStrbufEqualS(&result->processName, "proot") ||
|
||||
ffStrbufEqualS(&result->processName, "script") ||
|
||||
ffStrbufEqualS(&result->processName, "init") ||
|
||||
ffStrbufEqualS(&result->processName, "systemd") ||
|
||||
#ifdef __linux__
|
||||
ffStrbufStartsWithS(&result->processName, "flatpak-") || // #707
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,3 @@
|
||||
|
||||
#define FASTFETCH_DATATEXT_JSON_HELP @DATATEXT_JSON_HELP@
|
||||
#define FASTFETCH_DATATEXT_STRUCTURE @DATATEXT_STRUCTURE@
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define FASTFETCH_DATATEXT_NOWPLAYING @DATATEXT_NOWPLAYING@
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$2,--, $1| $2,--,
|
||||
$2| `-, $1,^, $2,-' |
|
||||
$2 `, `-, $3(/ \) $2,-' ,'
|
||||
$2 `, `-, $1(/ \) $2,-' ,'
|
||||
$2 `-, `-,$1/ \$2,-' ,-'
|
||||
$2 `------$1( )$2------'
|
||||
$2 ,----------$1( )$2----------,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
__ygg@@@@@@@@@ggy__
|
||||
_yg@@@@@@@@@@@@@@@@@@@@@gy_
|
||||
_a@@@@@@@@@@@@@@@@@@@@@@@@@@@@@y_
|
||||
_a@@@@@@@@@@@@@@@@@@@@@@@$2#$1@@@@@@@@@g_
|
||||
a@@@@@@@@@@@@@$2###$1@@@@@@@@$2##$1@@@@$2##$1@@@@@k
|
||||
g@@@@@@@$2###$1@@@$2#####$1@@@@@@@$2##$1@@$2###$1@@@@@@@k
|
||||
a@@@@@@@@$2#####$1@$2#####$1@@@@@@$2##$1@@$2###$1@@@@@@@@@k
|
||||
j@@@@@@@@@$2############$1@@@@@$2##$1@$2###$1@@@@@@@@@@@k
|
||||
g@@@@@@@@@$2#####################$1@@@@@@@@@@@@@@
|
||||
@@@@@@@@@$2##########################$1@@@@@@@@@@
|
||||
0@@@@@@@@$2###########################$1@@@@@@@@@
|
||||
~@@@@@@@$2############################$1@@@@@@@@F
|
||||
9@@@@@@$2##########################$1@@@@@@@@@P
|
||||
4@@@@@@$2######################$1@@@@@@@@@@@P
|
||||
~@@@@@@$2################$1@@@@@@@@@@@@@@@F
|
||||
`4@@@@@@$2#######$1@@@@@@@@@@@@@@@@@@@@P`
|
||||
`~@@@@@@@@@@@@@@@@@@@@@@@@@@@@@F`
|
||||
~~4@@@@@@@@@@@@@@@@@@@@@P~~
|
||||
`~~=R@@@@@@@@@P=~~~
|
||||
+202
-192
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ static void* logoResize(const void* image, size_t width, size_t height, void* ex
|
||||
FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
|
||||
{
|
||||
FF_LIBRARY_LOAD(imageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
|
||||
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||
.resizeFunc = logoResize,
|
||||
|
||||
@@ -19,7 +19,7 @@ FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
|
||||
"libMagickCore-7.Q16" FF_LIBRARY_EXTENSION, 11,
|
||||
"libMagickCore-7.Q16HDRI-10" FF_LIBRARY_EXTENSION, -1 // Required for Windows
|
||||
)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
|
||||
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||
.resizeFunc = logoResize,
|
||||
|
||||
@@ -708,8 +708,8 @@ static bool printImageChafa(FFLogoRequestData* requestData, const ImageData* ima
|
||||
|
||||
FFLogoImageResult ffLogoPrintImageImpl(FFLogoRequestData* requestData, const FFIMData* imData)
|
||||
{
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreGenesis, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreTerminus, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreGenesis, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, MagickCoreTerminus, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, AcquireExceptionInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, DestroyExceptionInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imData->library, AcquireImageInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
|
||||
@@ -27,6 +27,12 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
|
||||
if (*percent == *percent)
|
||||
{
|
||||
sumValue += *percent;
|
||||
|
||||
#if WIN32
|
||||
// Windows may return values greater than 100%, cap them to 100%
|
||||
if (*percent > 100) *percent = 100;
|
||||
#endif
|
||||
|
||||
if (*percent > maxValue)
|
||||
{
|
||||
maxValue = *percent;
|
||||
@@ -42,6 +48,10 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options)
|
||||
++index;
|
||||
}
|
||||
double avgValue = sumValue / (double) valueCount;
|
||||
#if WIN32
|
||||
// See above comment
|
||||
if (avgValue > 100) avgValue = 100;
|
||||
#endif
|
||||
|
||||
FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type;
|
||||
|
||||
|
||||
@@ -63,6 +63,13 @@ typedef struct _PERF_COUNTER_HEADER {
|
||||
// If dwType == PERF_COUNTERSET: PERF_MULTI_COUNTERS block + PERF_MULTI_INSTANCES block.
|
||||
} PERF_COUNTER_HEADER, * PPERF_COUNTER_HEADER;
|
||||
|
||||
typedef struct _PERF_MULTI_INSTANCES {
|
||||
ULONG dwTotalSize; // = sizeof(PERF_MULTI_INSTANCES) + sizeof(instance data blocks...)
|
||||
ULONG dwInstances; // Number of instance data blocks.
|
||||
// Followed by:
|
||||
// Instance data blocks...;
|
||||
} PERF_MULTI_INSTANCES, * PPERF_MULTI_INSTANCES;
|
||||
|
||||
typedef struct _PERF_MULTI_COUNTERS {
|
||||
ULONG dwSize; // sizeof(PERF_MULTI_COUNTERS) + sizeof(CounterIds)
|
||||
ULONG dwCounters; // Number of counter ids.
|
||||
Reference in New Issue
Block a user