From 01f400c15f1bff8217c9d4c6f24316b7b254757d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 5 Feb 2025 02:08:28 +0100 Subject: [PATCH] Haiku: minimal implementation (#1538) --- CMakeLists.txt | 77 ++++++++++++++++++- src/common/io/io_unix.c | 2 +- src/common/netif/netif_haiku.c | 63 +++++++++++++++ .../displayserver/displayserver_haiku.cpp | 72 +++++++++++++++++ src/detection/dns/dns_linux.c | 8 +- src/detection/font/font.h | 1 + src/detection/font/font_haiku.cpp | 65 ++++++++++++++++ src/detection/localip/localip_linux.c | 23 +++++- src/detection/memory/memory_haiku.c | 15 ++++ src/detection/os/os_haiku.c | 20 +++++ src/detection/packages/packages.c | 2 +- src/detection/packages/packages_haiku.c | 13 ++++ src/detection/processes/processes_haiku.c | 14 ++++ src/detection/swap/swap_haiku.c | 17 ++++ src/detection/uptime/uptime_haiku.c | 11 +++ src/detection/version/version.c | 2 + src/util/platform/FFPlatform_unix.c | 23 ++++++ 17 files changed, 420 insertions(+), 8 deletions(-) create mode 100644 src/common/netif/netif_haiku.c create mode 100644 src/detection/displayserver/displayserver_haiku.cpp create mode 100644 src/detection/font/font_haiku.cpp create mode 100644 src/detection/memory/memory_haiku.c create mode 100644 src/detection/os/os_haiku.c create mode 100644 src/detection/packages/packages_haiku.c create mode 100644 src/detection/processes/processes_haiku.c create mode 100644 src/detection/swap/swap_haiku.c create mode 100644 src/detection/uptime/uptime_haiku.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d120d37bc..85922e0d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index 69b6fbca6..5623d2dc9 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -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 diff --git a/src/common/netif/netif_haiku.c b/src/common/netif/netif_haiku.c new file mode 100644 index 000000000..a08f63580 --- /dev/null +++ b/src/common/netif/netif_haiku.c @@ -0,0 +1,63 @@ +#include "netif.h" +#include "common/io/io.h" +#include "util/mallocHelper.h" + +#include +#include +#include +#include +#include +#include + +// 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; +} diff --git a/src/detection/displayserver/displayserver_haiku.cpp b/src/detection/displayserver/displayserver_haiku.cpp new file mode 100644 index 000000000..b6f2e869d --- /dev/null +++ b/src/detection/displayserver/displayserver_haiku.cpp @@ -0,0 +1,72 @@ +extern "C" { +#include "displayserver.h" +#include "common/settings.h" +#include "common/processing.h" +} + +#include + +#include +#include + +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); +} diff --git a/src/detection/dns/dns_linux.c b/src/detection/dns/dns_linux.c index 1179ea4a9..8bf1da0c2 100644 --- a/src/detection/dns/dns_linux.c +++ b/src/detection/dns/dns_linux.c @@ -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"; diff --git a/src/detection/font/font.h b/src/detection/font/font.h index f0c59bba7..0f0e28d1f 100644 --- a/src/detection/font/font.h +++ b/src/detection/font/font.h @@ -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]; diff --git a/src/detection/font/font_haiku.cpp b/src/detection/font/font_haiku.cpp new file mode 100644 index 000000000..5f64aecd8 --- /dev/null +++ b/src/detection/font/font_haiku.cpp @@ -0,0 +1,65 @@ +extern "C" { +#include "common/font.h" +#include "common/parsing.h" +#include "font.h" +} + +#include +#include +#include + +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; +} diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 7a8552811..f9cc343d6 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -18,23 +18,27 @@ #include #endif -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__HAIKU__) #include #include #else #include #endif -#ifdef __sun +#if defined(__sun) || defined(__HAIKU__) #include #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)) diff --git a/src/detection/memory/memory_haiku.c b/src/detection/memory/memory_haiku.c new file mode 100644 index 000000000..b69ddfa34 --- /dev/null +++ b/src/detection/memory/memory_haiku.c @@ -0,0 +1,15 @@ +#include "memory.h" + +#include + +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; +} diff --git a/src/detection/os/os_haiku.c b/src/detection/os/os_haiku.c new file mode 100644 index 000000000..f31fb28fb --- /dev/null +++ b/src/detection/os/os_haiku.c @@ -0,0 +1,20 @@ +#include "os.h" +#include "common/io/io.h" + +#include + +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? +} diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 47cf99b6c..373256568 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -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 diff --git a/src/detection/packages/packages_haiku.c b/src/detection/packages/packages_haiku.c new file mode 100644 index 000000000..b66edefbb --- /dev/null +++ b/src/detection/packages/packages_haiku.c @@ -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); +} diff --git a/src/detection/processes/processes_haiku.c b/src/detection/processes/processes_haiku.c new file mode 100644 index 000000000..8e373729e --- /dev/null +++ b/src/detection/processes/processes_haiku.c @@ -0,0 +1,14 @@ +#include "processes.h" + +#include + +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; +} diff --git a/src/detection/swap/swap_haiku.c b/src/detection/swap/swap_haiku.c new file mode 100644 index 000000000..b61f213e7 --- /dev/null +++ b/src/detection/swap/swap_haiku.c @@ -0,0 +1,17 @@ +#include "swap.h" + +#include + +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; +} diff --git a/src/detection/uptime/uptime_haiku.c b/src/detection/uptime/uptime_haiku.c new file mode 100644 index 000000000..46af1115e --- /dev/null +++ b/src/detection/uptime/uptime_haiku.c @@ -0,0 +1,11 @@ +#include "uptime.h" +#include "common/time.h" + +#include + +const char* ffDetectUptime(FFUptimeResult* result) +{ + result->uptime = system_time() / 1000; + result->bootTime = (real_time_clock_usecs() / 1000) - result->uptime; + return NULL; +} diff --git a/src/detection/version/version.c b/src/detection/version/version.c index a979bde5f..ce493344a 100644 --- a/src/detection/version/version.c +++ b/src/detection/version/version.c @@ -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 diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index c8b5c7c65..88944c4a4 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -14,6 +14,9 @@ #include #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #include +#elif defined(__HAIKU__) + #include + #include #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);