Haiku: minimal implementation (#1538)

This commit is contained in:
François Revol
2025-02-05 02:08:28 +01:00
committed by GitHub
parent 33c905aa99
commit 01f400c15f
17 changed files with 420 additions and 8 deletions
+76 -1
View File
@@ -30,6 +30,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
set(DragonFly TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
set(SunOS TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku")
set(Haiku TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT WIN32)
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
endif()
@@ -139,7 +141,7 @@ set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=retu
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
if(WIN32 OR HAIKU OR ENABLE_DIRECTX_HEADERS)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
@@ -1088,6 +1090,74 @@ elseif(SunOS)
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(Haiku)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_unix.c
src/common/netif/netif_haiku.c
src/common/networking_linux.c
src/common/processing_linux.c
src/detection/battery/battery_nosupport.c
src/detection/bios/bios_nosupport.c
src/detection/board/board_nosupport.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_nosupport.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpuusage/cpuusage_nosupport.c
src/detection/cursor/cursor_nosupport.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/disk/disk_nosupport.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_nosupport.c
src/detection/displayserver/displayserver_haiku.cpp
src/detection/font/font_haiku.cpp
src/detection/gpu/gpu_nosupport.c
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_nosupport.c
src/detection/icons/icons_nosupport.c
src/detection/initsystem/initsystem_nosupport.c
src/detection/keyboard/keyboard_nosupport.c
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/media/media_nosupport.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/os/os_uname.c
src/detection/packages/packages_haiku.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_haiku.c
src/detection/gtk_qt/qt.c
src/detection/sound/sound_nosupport.c
src/detection/swap/swap_haiku.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_haiku.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/camera/camera_nosupport.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
endif()
if(ENABLE_DIRECTX_HEADERS)
@@ -1534,6 +1604,11 @@ elseif(ANDROID)
)
endif()
endif()
elseif(Haiku)
target_link_libraries(libfastfetch
PRIVATE "network"
PRIVATE "be"
)
endif()
target_include_directories(libfastfetch
+1 -1
View File
@@ -310,7 +310,7 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
continue;
bool isDir = false;
#ifndef __sun
#if !defined(__sun) && !defined(__HAIKU__)
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
isDir = entry->d_type == DT_DIR;
else
+63
View File
@@ -0,0 +1,63 @@
#include "netif.h"
#include "common/io/io.h"
#include "util/mallocHelper.h"
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <stdio.h>
// losely based on Haiku's src/bin/network/route/route.cpp
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
{
// TODO: AF_INET6
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET);
if (pfRoute < 0)
return false;
struct ifconf config;
config.ifc_len = sizeof(config.ifc_value);
if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0)
return false;
int size = config.ifc_value;
if (size == 0)
return false;
FF_AUTO_FREE void *buffer = malloc(size);
if (buffer == NULL) {
return false;
}
config.ifc_len = size;
config.ifc_buf = buffer;
if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0)
return false;
struct ifreq *interface = (struct ifreq*)buffer;
struct ifreq *end = (struct ifreq*)((uint8_t*)buffer + size);
while (interface < end) {
if (interface->ifr_route.flags & RTF_DEFAULT) {
strlcpy(iface, interface->ifr_name, IF_NAMESIZE);
*ifIndex = if_nametoindex(interface->ifr_name);
return true;
}
size_t addressSize = 0;
if (interface->ifr_route.destination != NULL)
addressSize += interface->ifr_route.destination->sa_len;
if (interface->ifr_route.mask != NULL)
addressSize += interface->ifr_route.mask->sa_len;
if (interface->ifr_route.gateway != NULL)
addressSize += interface->ifr_route.gateway->sa_len;
interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE
+ sizeof(struct route_entry) + addressSize);
}
return false;
}
@@ -0,0 +1,72 @@
extern "C" {
#include "displayserver.h"
#include "common/settings.h"
#include "common/processing.h"
}
#include <math.h>
#include <Application.h>
#include <Screen.h>
extern "C" void ffConnectDisplayServerImpl(FFDisplayServerResult* ds);
static void detectDisplays(FFDisplayServerResult* ds)
{
// We need a valid be_app to query the app_server here.
BApplication app("application/x-vnd.fastfetch-cli-fastfetch");
BScreen s{}; // default screen is the main one
bool main = true;
do
{
if (!s.IsValid())
continue;
display_mode mode;
if (s.GetMode(&mode) != B_OK)
continue;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateA(128);
monitor_info monitor;
// WARNING: This is experimental new Haiku API
status_t err = s.GetMonitorInfo(&monitor);
if (err == B_OK) {
ffStrbufSetF(&name, "%s %s", monitor.vendor, monitor.name);
}
uint32_t width = (uint32_t) s.Frame().Width() + 1;
uint32_t height = (uint32_t) (uint32_t)s.Frame().Height() + 1;
double scaleFactor = (double) 1.0;
ffdsAppendDisplay(ds,
width,
height,
(double)mode.timing.pixel_clock * 1000 / (mode.timing.v_total * mode.timing.h_total),
(uint32_t) (width / scaleFactor + .5),
(uint32_t) (height / scaleFactor + .5),
0,
0,
0,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
main,
s.ID().id,
0,
0,
"BScreen"
);
main = false;
} while (s.SetToNext() == B_OK);
return;
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
{
ffStrbufSetStatic(&ds->wmProcessName, "app_server");
ffStrbufSetStatic(&ds->wmPrettyName, "Application Server");
ffStrbufSetStatic(&ds->dePrettyName, "Application Kit");
detectDisplays(ds);
}
+7 -1
View File
@@ -4,9 +4,15 @@
#include "util/mallocHelper.h"
#include "util/stringUtils.h"
#ifdef __HAIKU__
#define RESOLV_CONF "/system/settings/network/resolv.conf"
#else
#define RESOLV_CONF "/etc/resolv.conf"
#endif
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
{
FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf", "r");
FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT RESOLV_CONF, "r");
if (!file)
return "fopen (" FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf) failed";
+1
View File
@@ -10,6 +10,7 @@ typedef struct FFFontResult
* Linux / BSD: Qt, GTK2, GTK3, GTK4
* MacOS: System, User, System Mono, User Mono
* Windows: Caption, Menu, Message, Status
* Haiku: Plain, Menu, Bold, Mono
* Other: Unset, Unset, Unset, Unset
*/
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
+65
View File
@@ -0,0 +1,65 @@
extern "C" {
#include "common/font.h"
#include "common/parsing.h"
#include "font.h"
}
#include <Application.h>
#include <Font.h>
#include <Menu.h>
extern "C" {
const char* ffDetectFontImpl(FFFontResult* result);
}
static void generateString(FFFontResult* font)
{
const char* types[] = { "Plain", "Menu", "Bold", "Mono" };
for(uint32_t i = 0; i < ARRAY_SIZE(types); ++i)
{
if(i == 0 || !ffStrbufEqual(&font->fonts[i - 1], &font->fonts[i]))
{
if(i > 0)
ffStrbufAppendS(&font->display, "], ");
ffStrbufAppendF(&font->display, "%s [%s", font->fonts[i].chars, types[i]);
}
else
{
ffStrbufAppendS(&font->display, " / ");
ffStrbufAppendS(&font->display, types[i]);
}
}
ffStrbufAppendC(&font->display, ']');
}
const char* ffDetectFontImpl(FFFontResult* result)
{
struct menu_info menuInfo;
const BFont *f;
// We need a valid be_app to query the app_server here.
BApplication app("application/x-vnd.fastfetch-cli-fastfetch");
if ((f = be_plain_font) != NULL)
{
f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style);
ffStrbufAppendF(&result->fonts[0], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size());
}
if (get_menu_info(&menuInfo) == B_OK)
{
ffStrbufAppendF(&result->fonts[1], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)menuInfo.font_size);
}
if ((f = be_bold_font) != NULL)
{
f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style);
ffStrbufAppendF(&result->fonts[2], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size());
}
if ((f = be_fixed_font) != NULL)
{
f->GetFamilyAndStyle(&menuInfo.f_family, &menuInfo.f_style);
ffStrbufAppendF(&result->fonts[3], "%s %s (%dpt)", menuInfo.f_family, menuInfo.f_style, (int)f->Size());
}
generateString(result);
return NULL;
}
+19 -4
View File
@@ -18,23 +18,27 @@
#include <linux/if.h>
#endif
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__HAIKU__)
#include <net/if_media.h>
#include <net/if_dl.h>
#else
#include <netpacket/packet.h>
#endif
#ifdef __sun
#if defined(__sun) || defined(__HAIKU__)
#include <sys/sockio.h>
#endif
static const FFLocalIpNIFlag niFlagOptions[] = {
{ IFF_UP, "UP" },
{ IFF_BROADCAST, "BROADCAST" },
#ifdef IFF_DEBUG
{ IFF_DEBUG, "DEBUG" },
#endif
{ IFF_LOOPBACK, "LOOPBACK" },
{ IFF_POINTOPOINT, "POINTOPOINT" },
#ifdef IFF_RUNNING
{ IFF_RUNNING, "RUNNING" },
#endif
{ IFF_NOARP, "NOARP" },
{ IFF_PROMISC, "PROMISC" },
{ IFF_ALLMULTI, "ALLMULTI" },
@@ -64,6 +68,13 @@ static const FFLocalIpNIFlag niFlagOptions[] = {
#endif
#ifdef IFF_CANTCONFIG
{ IFF_CANTCONFIG, "CANTCONFIG" },
#endif
#ifdef __HAIKU__
{ IFF_AUTOUP, "IAUTOUP" },
{ IFF_SIMPLEX, "SIMPLEX" },
{ IFF_LINK, "LINK" },
{ IFF_AUTO_CONFIGURED, "AUTO_CONFIGURED" },
{ IFF_CONFIGURING, "CONFIGURING" },
#endif
// sentinel
{},
@@ -128,8 +139,12 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
for (struct ifaddrs* ifa = ifAddrStruct; ifa; ifa = ifa->ifa_next)
{
if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING))
if (!ifa->ifa_addr)
continue;
#ifdef IFF_RUNNING
if (!(ifa->ifa_flags & IFF_RUNNING))
continue;
#endif
bool isDefaultRoute = ffStrEquals(defaultRouteIfName, ifa->ifa_name);
if ((options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT) && !isDefaultRoute)
@@ -190,7 +205,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
}
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__
#if __FreeBSD__ || __OpenBSD__ || __APPLE__ || __NetBSD__ || __HAIKU__
else if (ifa->ifa_addr->sa_family == AF_LINK)
{
if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT))
+15
View File
@@ -0,0 +1,15 @@
#include "memory.h"
#include <OS.h>
const char* ffDetectMemory(FFMemoryResult* ram)
{
system_info info;
if (get_system_info(&info) != B_OK)
return "Error getting system info";
ram->bytesTotal = B_PAGE_SIZE * info.max_pages;
ram->bytesUsed = B_PAGE_SIZE * info.used_pages;
return NULL;
}
+20
View File
@@ -0,0 +1,20 @@
#include "os.h"
#include "common/io/io.h"
#include <OS.h>
void ffDetectOSImpl(FFOSResult* os)
{
system_info info;
ffStrbufSetStatic(&os->name, "Haiku");
ffStrbufSetStatic(&os->prettyName, "Haiku");
ffStrbufSetStatic(&os->id, "haiku");
if (get_system_info(&info) != B_OK)
return;
ffStrbufAppendF(&os->version, "R%lld", info.kernel_version);
// TODO: check kernel resources?
}
+1 -1
View File
@@ -100,7 +100,7 @@ uint32_t ffPackagesGetNumElements(const char* dirname, bool isdir)
{
bool ok = false;
#ifndef __sun
#if !defined(__sun) && !defined(__HAIKU__)
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
ok = entry->d_type == (isdir ? DT_DIR : DT_REG);
else
+13
View File
@@ -0,0 +1,13 @@
#include "packages.h"
#include "common/io/io.h"
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
{
// TODO: Use the Package Kit C++ API instead (would account for disabled packages)
if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT))
result->pkg = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/system/packages", false);
if (!(options->disabled & FF_PACKAGES_FLAG_PKGSRC_BIT))
result->pkgsrc = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/boot/home/config/packages", false);
}
+14
View File
@@ -0,0 +1,14 @@
#include "processes.h"
#include <OS.h>
const char* ffDetectProcesses(uint32_t* result)
{
system_info info;
if (get_system_info(&info) != B_OK)
return "Error getting system info";
*result = info.used_teams;
return NULL;
}
+17
View File
@@ -0,0 +1,17 @@
#include "swap.h"
#include <OS.h>
enum { FFMaxNSwap = 8 };
const char* ffDetectSwap(FFSwapResult* swap)
{
system_info info;
if (get_system_info(&info) != B_OK)
return "Error getting system info";
swap->bytesTotal = B_PAGE_SIZE * info.max_swap_pages;
swap->bytesUsed = B_PAGE_SIZE * (info.max_swap_pages - info.free_swap_pages);
return NULL;
}
+11
View File
@@ -0,0 +1,11 @@
#include "uptime.h"
#include "common/time.h"
#include <OS.h>
const char* ffDetectUptime(FFUptimeResult* result)
{
result->uptime = system_time() / 1000;
result->bootTime = (real_time_clock_usecs() / 1000) - result->uptime;
return NULL;
}
+2
View File
@@ -42,6 +42,8 @@
#define FF_SYSNAME "OpenBSD"
#elif defined(__NetBSD__)
#define FF_SYSNAME "NetBSD"
#elif defined(__HAIKU__)
#define FF_SYSNAME "Haiku"
#else
#define FF_SYSNAME "unknown"
#endif
+23
View File
@@ -14,6 +14,9 @@
#include <sys/sysctl.h>
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/sysctl.h>
#elif defined(__HAIKU__)
#include <image.h>
#include <OS.h>
#endif
static void getExePath(FFPlatform* platform)
@@ -47,6 +50,17 @@ static void getExePath(FFPlatform* platform)
ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1);
if (exePathLen >= 0)
exePath[exePathLen] = '\0';
#elif defined(__HAIKU__)
size_t exePathLen = 0;
image_info info;
int32 cookie = 0;
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
if (info.type == B_APP_IMAGE) {
exePathLen = strlcpy(exePath, info.name, PATH_MAX);
break;
}
}
#endif
if (exePathLen > 0)
{
@@ -117,6 +131,9 @@ static void getConfigDirs(FFPlatform* platform)
ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Preferences/");
ffPlatformPathAddHome(&platform->configDirs, platform, "Library/Application Support/");
#endif
#if defined(__HAIKU__)
ffPlatformPathAddHome(&platform->configDirs, platform, "config/settings/");
#endif
ffPlatformPathAddHome(&platform->configDirs, platform, "");
platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS");
@@ -185,6 +202,12 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts)
ffStrbufAppendS(&info->name, uts->sysname);
ffStrbufAppendS(&info->release, uts->release);
ffStrbufAppendS(&info->version, uts->version);
#ifdef __HAIKU__
/* historical reason */
if (!strcmp(uts->machine, "BePC"))
ffStrbufAppendS(&info->architecture, "i386");
else
#endif
ffStrbufAppendS(&info->architecture, uts->machine);
ffStrbufInit(&info->displayVersion);