diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cb52dc5d4..1e698be610 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1132,13 +1132,13 @@ elseif(Haiku) src/detection/chassis/chassis_windows.c src/detection/cpu/cpu_haiku.c src/detection/cpucache/cpucache_shared.c - src/detection/cpuusage/cpuusage_nosupport.c + src/detection/cpuusage/cpuusage_haiku.c src/detection/cursor/cursor_nosupport.c - src/detection/bluetooth/bluetooth_nosupport.c + src/detection/bluetooth/bluetooth_haiku.cpp src/detection/bluetoothradio/bluetoothradio_nosupport.c src/detection/disk/disk_haiku.cpp src/detection/dns/dns_linux.c - src/detection/physicaldisk/physicaldisk_nosupport.c + src/detection/physicaldisk/physicaldisk_haiku.c src/detection/physicalmemory/physicalmemory_linux.c src/detection/diskio/diskio_nosupport.c src/detection/displayserver/displayserver_haiku.cpp @@ -1149,18 +1149,18 @@ elseif(Haiku) src/detection/host/host_windows.c src/detection/icons/icons_nosupport.c src/detection/initsystem/initsystem_haiku.cpp - src/detection/keyboard/keyboard_nosupport.c + src/detection/keyboard/keyboard_haiku.cpp src/detection/libc/libc_nosupport.c src/detection/lm/lm_nosupport.c src/detection/loadavg/loadavg_nosupport.c src/detection/locale/locale_linux.c src/detection/localip/localip_linux.c - src/detection/gamepad/gamepad_nosupport.c + src/detection/gamepad/gamepad_haiku.cpp src/detection/media/media_linux.c src/detection/memory/memory_haiku.c - src/detection/mouse/mouse_nosupport.c - src/detection/netio/netio_nosupport.c - src/detection/opengl/opengl_linux.c + src/detection/mouse/mouse_haiku.cpp + src/detection/netio/netio_haiku.cpp + src/detection/opengl/opengl_haiku.cpp src/detection/os/os_haiku.c src/detection/packages/packages_haiku.c src/detection/poweradapter/poweradapter_nosupport.c @@ -1646,7 +1646,11 @@ elseif(ANDROID) elseif(Haiku) target_link_libraries(libfastfetch PRIVATE "network" + PRIVATE "bnetapi" PRIVATE "media" + PRIVATE "device" + PRIVATE "bluetooth" + PRIVATE "GL" PRIVATE "be" PRIVATE "gnu" ) diff --git a/presets/all.jsonc b/presets/all.jsonc index 6b54692723..d1e30ef4c5 100644 --- a/presets/all.jsonc +++ b/presets/all.jsonc @@ -90,6 +90,8 @@ "sound", "camera", "gamepad", + "mouse", + "keyboard", { "type": "weather", "timeout": 1000 diff --git a/presets/ci.jsonc b/presets/ci.jsonc index eb3a0c2195..a1e9da42bb 100644 --- a/presets/ci.jsonc +++ b/presets/ci.jsonc @@ -92,6 +92,8 @@ "sound", "camera", "gamepad", + "mouse", + "keyboard", { "type": "weather", "timeout": 1000 diff --git a/src/detection/bluetooth/bluetooth_haiku.cpp b/src/detection/bluetooth/bluetooth_haiku.cpp new file mode 100644 index 0000000000..89ae13624e --- /dev/null +++ b/src/detection/bluetooth/bluetooth_haiku.cpp @@ -0,0 +1,29 @@ +extern "C" { +#include "bluetooth.h" +#include "common/io/io.h" +} + +#include + +const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */) +{ + using namespace Bluetooth; + FF_SUPPRESS_IO(); + + LocalDevice* dev = LocalDevice::GetLocalDevice(); + if (!dev) return NULL; + + BString devClass; + dev->GetDeviceClass().DumpDeviceClass(devClass); + + FFBluetoothResult* device = (FFBluetoothResult*) ffListAdd(devices); + ffStrbufInitS(&device->name, dev->GetFriendlyName()); + ffStrbufInitS(&device->address, bdaddrUtils::ToString(dev->GetBluetoothAddress()).String()); + ffStrbufInitS(&device->type, devClass.String()); + device->battery = 0; + device->connected = true; + + // TODO: more devices? + + return NULL; +} diff --git a/src/detection/cpuusage/cpuusage_haiku.c b/src/detection/cpuusage/cpuusage_haiku.c new file mode 100644 index 0000000000..88a734ee29 --- /dev/null +++ b/src/detection/cpuusage/cpuusage_haiku.c @@ -0,0 +1,27 @@ +#include "fastfetch.h" +#include "detection/cpuusage/cpuusage.h" +#include "util/mallocHelper.h" + +#include + +const char* ffGetCpuUsageInfo(FFlist* cpuTimes) +{ + system_info sysInfo; + if (get_system_info(&sysInfo) != B_OK) + return "get_system_info() failed"; + + FF_AUTO_FREE cpu_info* cpuInfo = malloc(sizeof(*cpuInfo) * sysInfo.cpu_count); + if (get_cpu_info(0, sysInfo.cpu_count, cpuInfo) != B_OK) + return "get_cpu_info() failed"; + + uint64_t uptime = (uint64_t) system_time(); + + for (uint32_t i = 0; i < sysInfo.cpu_count; ++i) + { + FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes); + info->inUseAll = (uint64_t) cpuInfo[i].active_time; + info->totalAll = uptime; + } + + return NULL; +} diff --git a/src/detection/disk/disk_haiku.cpp b/src/detection/disk/disk_haiku.cpp index 504ec797d9..69f766fed1 100644 --- a/src/detection/disk/disk_haiku.cpp +++ b/src/detection/disk/disk_haiku.cpp @@ -1,19 +1,33 @@ extern "C" { #include "disk.h" +#include "util/stringUtils.h" } #include #include #include -const char* ffDetectDisksImpl(FF_MAYBE_UNUSED FFDiskOptions* options, FF_MAYBE_UNUSED FFlist* disks) +const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) { int32 pos = 0; for (dev_t dev; (dev = next_dev(&pos)) >= B_OK;) { fs_info fs; - fs_stat_dev(dev, &fs); + if (fs_stat_dev(dev, &fs) < -1) continue; + + if (!ffStrStartsWith(fs.device_name, "/dev/")) continue; // physical disks only + + node_ref node(fs.dev, fs.root); + BDirectory dir(&node); + BPath path(&dir); + if (path.InitCheck() != B_OK) continue; + + if (__builtin_expect(options->folders.length, 0)) + { + if (!ffDiskMatchMountpoint(options, path.Path())) + continue; + } FFDisk* disk = (FFDisk*) ffListAdd(disks); @@ -26,16 +40,7 @@ const char* ffDetectDisksImpl(FF_MAYBE_UNUSED FFDiskOptions* options, FF_MAYBE_U disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs.free_nodes); ffStrbufInitS(&disk->mountFrom, fs.device_name); - ffStrbufInit(&disk->mountpoint); - { - node_ref node(fs.dev, fs.root); - BDirectory dir(&node); - BPath path(&dir); - if (path.InitCheck() == B_OK) - ffStrbufSetS(&disk->mountpoint, path.Path()); - else - ffStrbufSetStatic(&disk->mountpoint, "?"); - } + ffStrbufInitS(&disk->mountpoint, path.Path()); ffStrbufInitS(&disk->filesystem, fs.fsh_name); ffStrbufInitS(&disk->name, fs.volume_name); disk->type = FF_DISK_VOLUME_TYPE_NONE; @@ -45,7 +50,12 @@ const char* ffDetectDisksImpl(FF_MAYBE_UNUSED FFDiskOptions* options, FF_MAYBE_U disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_READONLY_BIT); if (fs.flags & B_FS_IS_REMOVABLE) disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT); + if (disk->type == FF_DISK_VOLUME_TYPE_NONE) disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT; disk->createTime = 0; + + time_t crTime; + if (dir.GetCreationTime(&crTime) == B_OK) + disk->createTime = (uint64_t) crTime * 1000; } - return 0; + return NULL; } diff --git a/src/detection/font/font_haiku.cpp b/src/detection/font/font_haiku.cpp index 5f64aecd8f..0e0eb6751f 100644 --- a/src/detection/font/font_haiku.cpp +++ b/src/detection/font/font_haiku.cpp @@ -1,6 +1,4 @@ extern "C" { -#include "common/font.h" -#include "common/parsing.h" #include "font.h" } diff --git a/src/detection/gamepad/gamepad_haiku.cpp b/src/detection/gamepad/gamepad_haiku.cpp new file mode 100644 index 0000000000..820836f077 --- /dev/null +++ b/src/detection/gamepad/gamepad_haiku.cpp @@ -0,0 +1,21 @@ +extern "C" { +#include "gamepad.h" +} +#include + +const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */) +{ + BJoystick js; + for (int32 i = 0, n = js.CountDevices(); i < n; ++i) + { + char name[B_OS_NAME_LENGTH]; + if (js.GetDeviceName(i, name) == B_OK) + { + FFGamepadDevice* device = (FFGamepadDevice*) ffListAdd(devices); + ffStrbufInit(&device->serial); + ffStrbufInitS(&device->name, name); + device->battery = 0; + } + } + return NULL; +} diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 793db62a7e..535b8bc3eb 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -115,7 +115,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount)) // For Apple gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; - gpu->coreUsage = 0.0/0.0; + gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET; CFDictionaryRef perfStatistics = NULL; uint64_t vramUsed = 0, vramTotal = 0; if (ffCfDictGetDict(properties, CFSTR("PerformanceStatistics"), &perfStatistics) == NULL) diff --git a/src/detection/gpu/gpu_general.c b/src/detection/gpu/gpu_general.c index fdffcdd90e..703b0b237a 100644 --- a/src/detection/gpu/gpu_general.c +++ b/src/detection/gpu/gpu_general.c @@ -36,6 +36,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* ffStrbufInit(&gpu->platformApi); 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 = ((uint64_t) dev->domain << 6) | ((uint64_t) dev->bus << 4) | ((uint64_t) dev->dev << 2) | (uint64_t) dev->func; diff --git a/src/detection/gpu/gpu_haiku.c b/src/detection/gpu/gpu_haiku.c index 31de1b8b97..c1324f7613 100644 --- a/src/detection/gpu/gpu_haiku.c +++ b/src/detection/gpu/gpu_haiku.c @@ -26,6 +26,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* ffStrbufInit(&gpu->platformApi); 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 = ((uint64_t) dev.bus << 4) | ((uint64_t) dev.device << 2) | (uint64_t) dev.function; @@ -40,4 +41,3 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* return NULL; } - diff --git a/src/detection/keyboard/keyboard_haiku.cpp b/src/detection/keyboard/keyboard_haiku.cpp new file mode 100644 index 0000000000..f165b00fd8 --- /dev/null +++ b/src/detection/keyboard/keyboard_haiku.cpp @@ -0,0 +1,27 @@ +extern "C" { +#include "keyboard.h" +} + +#include +#include + +const char* ffDetectKeyboard(FFlist* devices /* List of FFKeyboardDevice */) +{ + BList list; + + if (get_input_devices(&list) != B_OK) + return "get_input_devices() failed"; + + for (int32 i = 0, n = list.CountItems(); i < n; i++) + { + BInputDevice *device = (BInputDevice *) list.ItemAt(i); + if (device->Type() != B_KEYBOARD_DEVICE || !device->IsRunning()) + continue; + + FFKeyboardDevice* item = (FFKeyboardDevice*) ffListAdd(devices); + ffStrbufInit(&item->serial); + ffStrbufInitS(&item->name, device->Name()); + } + + return NULL; +} diff --git a/src/detection/mouse/mouse_haiku.cpp b/src/detection/mouse/mouse_haiku.cpp new file mode 100644 index 0000000000..1178a25b3c --- /dev/null +++ b/src/detection/mouse/mouse_haiku.cpp @@ -0,0 +1,27 @@ +extern "C" { +#include "mouse.h" +} + +#include +#include + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */) +{ + BList list; + + if (get_input_devices(&list) != B_OK) + return "get_input_devices() failed"; + + for (int32 i = 0, n = list.CountItems(); i < n; i++) + { + BInputDevice *device = (BInputDevice *) list.ItemAt(i); + if (device->Type() != B_POINTING_DEVICE || !device->IsRunning()) + continue; + + FFMouseDevice* item = (FFMouseDevice*) ffListAdd(devices); + ffStrbufInit(&item->serial); + ffStrbufInitS(&item->name, device->Name()); + } + + return NULL; +} diff --git a/src/detection/netio/netio.c b/src/detection/netio/netio.c index 0c40843881..666321c996 100644 --- a/src/detection/netio/netio.c +++ b/src/detection/netio/netio.c @@ -2,8 +2,6 @@ #include "common/time.h" -const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options); - static FFlist ioCounters1; static uint64_t time1; diff --git a/src/detection/netio/netio.h b/src/detection/netio/netio.h index 1dd9586a4c..de633a1072 100644 --- a/src/detection/netio/netio.h +++ b/src/detection/netio/netio.h @@ -17,3 +17,4 @@ typedef struct FFNetIOResult } FFNetIOResult; const char* ffDetectNetIO(FFlist* result, FFNetIOOptions* options); +const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options); diff --git a/src/detection/netio/netio_haiku.cpp b/src/detection/netio/netio_haiku.cpp new file mode 100644 index 0000000000..e0c62ebf21 --- /dev/null +++ b/src/detection/netio/netio_haiku.cpp @@ -0,0 +1,49 @@ +extern "C" { +#include "netio.h" +#include "common/netif/netif.h" +} + +#include +#include + +const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) +{ + BNetworkRoster& roster = BNetworkRoster::Default(); + + BNetworkInterface interface; + uint32 cookie = 0; + + uint32_t defaultRouteIfIndex = ffNetifGetDefaultRouteIfIndex(); + + while (roster.GetNextInterface(&cookie, interface) == B_OK) + { + if (!interface.Exists()) + continue; + + bool defaultRoute = interface.Index() == defaultRouteIfIndex; + if (options->defaultRouteOnly && !defaultRoute) + continue; + + if (options->namePrefix.length && strncmp(interface.Name(), options->namePrefix.chars, options->namePrefix.length) != 0) + continue; + + ifreq_stats stats = {}; + if (interface.GetStats(stats) != B_OK) continue; + + FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result); + *counters = (FFNetIOResult) { + .name = ffStrbufCreateS(interface.Name()), + .defaultRoute = defaultRoute, + .txBytes = stats.send.bytes, + .rxBytes = stats.receive.bytes, + .txPackets = stats.send.packets, + .rxPackets = stats.receive.packets, + .rxErrors = stats.receive.errors, + .txErrors = stats.send.errors, + .rxDrops = stats.receive.dropped, + .txDrops = stats.send.dropped + }; + } + + return NULL; +} diff --git a/src/detection/opengl/opengl_haiku.cpp b/src/detection/opengl/opengl_haiku.cpp new file mode 100644 index 0000000000..ce01033601 --- /dev/null +++ b/src/detection/opengl/opengl_haiku.cpp @@ -0,0 +1,39 @@ +#include + +extern "C" { +#include "opengl.h" +#include "common/io/io.h" +#if FF_HAVE_EGL +const char* ffOpenGLDetectByEGL(FFOpenGLResult* result); +#endif +void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglGetString); +} + +static const char* oglDetectOpenGL(FFOpenGLResult* result) +{ + BApplication app("application/x-vnd.fastfetch-cli-fastfetch"); + FF_SUPPRESS_IO(); + + BGLView glView(BRect(), "ff_ogl_view", B_FOLLOW_NONE, B_WILL_DRAW, BGL_RGB); + auto ffglGetString = (decltype(&glGetString)) glView.GetGLProcAddress("glGetString"); + if (!ffglGetString) return "glView.GetGLProcAddress() failed"; + ffOpenGLHandleResult(result, ffglGetString); + ffStrbufSetStatic(&result->library, "OpenGLKit"); + return NULL; +} + +const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) +{ + if (options->library == FF_OPENGL_LIBRARY_AUTO) + return oglDetectOpenGL(result); + else if (options->library == FF_OPENGL_LIBRARY_EGL) + { + #if FF_HAVE_EGL + return ffOpenGLDetectByEGL(result); + #else + return "fastfetch was compiled without egl support"; + #endif + } + else + return "Unsupported OpenGL library"; +} diff --git a/src/detection/physicaldisk/physicaldisk_haiku.c b/src/detection/physicaldisk/physicaldisk_haiku.c new file mode 100644 index 0000000000..fd23616888 --- /dev/null +++ b/src/detection/physicaldisk/physicaldisk_haiku.c @@ -0,0 +1,80 @@ +#include "physicaldisk.h" + +#include "common/io/io.h" + +#include +#include +#include +#include + +static const char* detectDisk(int dfd, const char* diskType, const char* diskId, FFlist* result) +{ + char buffer[64]; + snprintf(buffer, sizeof(buffer), "%s/master/raw", diskId); + FF_AUTO_CLOSE_FD int rawfd = openat(dfd, buffer, O_RDONLY); + if (rawfd < 0) + { + snprintf(buffer, sizeof(buffer), "%s/raw", diskId); + rawfd = openat(dfd, buffer, O_RDONLY); + if (rawfd < 0) return "raw device file not found"; + } + + device_geometry geometry; + if (ioctl(rawfd, B_GET_GEOMETRY, &geometry, sizeof(geometry)) < 0) + return "ioctl(B_GET_GEOMETRY) failed"; + + FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result); + + char name[B_OS_NAME_LENGTH]; + if (ioctl(rawfd, B_GET_DEVICE_NAME, name, sizeof(name)) == 0) + ffStrbufInitS(&device->name, name); + else + { + // ioctl reports `not a tty` for NVME drives for some reason + ffStrbufInitF(&device->name, "Unknown %s drive", diskType); + } + + ffStrbufInitF(&device->devPath, "/dev/disk/%s/%s", diskType, buffer); + ffStrbufInit(&device->serial); + ffStrbufInit(&device->revision); + ffStrbufInitS(&device->interconnect, diskType); + device->temperature = 0.0/0.0; + device->type = FF_PHYSICALDISK_TYPE_NONE; + device->type |= (geometry.read_only ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE) | + (geometry.removable ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED); + device->size = (uint64_t) geometry.cylinder_count * geometry.sectors_per_track * geometry.bytes_per_sector; + + return NULL; +} + +static const char* detectDiskType(int dfd, const char* diskType, FFlist* result) +{ + int newfd = openat(dfd, diskType, O_RDONLY); + if (newfd < 0) return "openat(dfd, diskType) failed"; + + FF_AUTO_CLOSE_DIR DIR* dir = fdopendir(newfd); + if (!dir) return "fdopendir(newfd) failed"; + + struct dirent* entry; + while((entry = readdir(dir))) + { + if (entry->d_name[0] == '.') continue; + detectDisk(newfd, diskType, entry->d_name, result); + } + return NULL; +} + +const char* ffDetectPhysicalDisk(FFlist* result, FF_MAYBE_UNUSED FFPhysicalDiskOptions* options) +{ + FF_AUTO_CLOSE_DIR DIR* dir = opendir("/dev/disk"); + if (!dir) return "opendir(/dev/disk) failed"; + + struct dirent* entry; + while((entry = readdir(dir))) + { + if (entry->d_name[0] == '.') continue; + detectDiskType(dirfd(dir), entry->d_name, result); + } + + return NULL; +} diff --git a/src/detection/sound/sound_haiku.cpp b/src/detection/sound/sound_haiku.cpp index eb31d76aab..ba2dd7aeb8 100644 --- a/src/detection/sound/sound_haiku.cpp +++ b/src/detection/sound/sound_haiku.cpp @@ -72,7 +72,7 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */) if (mute) { - bool isMute = false; + int32 isMute = false; size = sizeof(isMute); if (mute->GetValue(&isMute, &size, &when) == B_OK && isMute) return NULL; diff --git a/src/util/smbiosHelper.c b/src/util/smbiosHelper.c index be122d3e5b..fd5d29484e 100644 --- a/src/util/smbiosHelper.c +++ b/src/util/smbiosHelper.c @@ -236,6 +236,9 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() FF_AUTO_CLOSE_FD int fd = open("/dev/misc/mem", O_RDONLY); if (fd < 0) return NULL; + + // Works on legacy BIOS only + // See: https://wiki.osdev.org/System_Management_BIOS#UEFI_systems FF_AUTO_FREE uint8_t* smBiosBase = malloc(0x10000); if (pread(fd, smBiosBase, 0x10000, 0xF0000) != 0x10000) return NULL;