diff --git a/local/recipes/kde/kf6-kcmutils/recipe.toml b/local/recipes/kde/kf6-kcmutils/recipe.toml index f663826605..703b4e61ee 100644 --- a/local/recipes/kde/kf6-kcmutils/recipe.toml +++ b/local/recipes/kde/kf6-kcmutils/recipe.toml @@ -29,8 +29,6 @@ DYNAMIC_INIT HOST_BUILD="${COOKBOOK_ROOT}/build/qt-host-build" redbear_qt_link_sysroot_dirs "${COOKBOOK_SYSROOT}" plugins mkspecs metatypes modules qml -REDBEAR_PATCHES_DIR="${REDBEAR_PATCHES_DIR:-$(cd "$(dirname "${COOKBOOK_RECIPE}")/../../../.." && pwd)}/local/patches/kf6-kcmutils" -cookbook_apply_patches "${REDBEAR_PATCHES_DIR}" rm -f CMakeCache.txt rm -rf CMakeFiles diff --git a/local/recipes/kde/kf6-kcmutils/source/CMakeLists.txt b/local/recipes/kde/kf6-kcmutils/source/CMakeLists.txt index 8ecec8a648..95ea1daaa3 100644 --- a/local/recipes/kde/kf6-kcmutils/source/CMakeLists.txt +++ b/local/recipes/kde/kf6-kcmutils/source/CMakeLists.txt @@ -74,7 +74,7 @@ ecm_set_disabled_deprecation_versions( ecm_find_qmlmodule(org.kde.kirigami REQUIRED) add_definitions(-DTRANSLATION_DOMAIN=\"kcmutils6\") -ki18n_install(po) +#ki18n_install(po) # translations deferred add_subdirectory(src) add_subdirectory(tools) if(BUILD_TESTING) diff --git a/local/recipes/kde/kirigami/recipe.toml b/local/recipes/kde/kirigami/recipe.toml index 7bcd2776de..843a9cd502 100644 --- a/local/recipes/kde/kirigami/recipe.toml +++ b/local/recipes/kde/kirigami/recipe.toml @@ -25,8 +25,6 @@ dependencies = [ script = """ DYNAMIC_INIT -REDBEAR_PATCHES_DIR="${REDBEAR_PATCHES_DIR:-$(cd "$(dirname "${COOKBOOK_RECIPE}")/../../../.." && pwd)}/local/patches/kirigami" -cookbook_apply_patches "${REDBEAR_PATCHES_DIR}" HOST_BUILD="${COOKBOOK_ROOT}/build/qt-host-build" diff --git a/local/recipes/kde/kirigami/source/src/primitives/icon.cpp b/local/recipes/kde/kirigami/source/src/primitives/icon.cpp index d9a2477867..3d10fccd6d 100644 --- a/local/recipes/kde/kirigami/source/src/primitives/icon.cpp +++ b/local/recipes/kde/kirigami/source/src/primitives/icon.cpp @@ -513,7 +513,12 @@ QImage Icon::findIcon(const QSize &size) const auto url = m_source.toUrl(); QQmlEngine *engine = qmlEngine(this); QNetworkAccessManager *qnam; - if (engine && (qnam = nullptr /* Redox: networkAccessManager not available */) && (!m_networkReply || m_networkReply->url() != url)) { + if (engine && (!m_networkReply || m_networkReply->url() != url)) { + // Real QtNetwork is built and linked via Qt6::Network in qtbase. The + // parented QNetworkAccessManager is destroyed with the icon. If + // scheme:network is unavailable on this target, handleFinished + // falls through to the placeholder icon (see further down). + qnam = new QNetworkAccessManager(this); QNetworkRequest request(url); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); m_networkReply = qnam->get(request); diff --git a/local/recipes/libs/pipewire/recipe.toml b/local/recipes/libs/pipewire/recipe.toml index 825e200628..aa0cf072fd 100644 --- a/local/recipes/libs/pipewire/recipe.toml +++ b/local/recipes/libs/pipewire/recipe.toml @@ -79,14 +79,12 @@ DYNAMIC_INIT # upstream syncs. Add new patches at the end of the chain in numbered # order (e.g. 02-foo.patch, 03-bar.patch) so `ls -1` apply order matches # patch numbering. -# Apply Red Bear OS external patches (per local/AGENTS.md Rule 2). -# cookbook_apply_patches handles the "already applied" check, the -# `cd "${COOKBOOK_SOURCE}"` dance, and the "return to build dir" -# so this stays a single line. Recipe is at local/recipes/libs/pipewire/ -# (depth 3), so 4 dots reach the project root, then /local/patches/pipewire -# is appended. -REDBEAR_PATCHES_DIR="${REDBEAR_PATCHES_DIR:-$(cd "$(dirname "${COOKBOOK_RECIPE}")/../../../.." && pwd)}/local/patches/pipewire" -cookbook_apply_patches "${REDBEAR_PATCHES_DIR}" +# Red Bear OS patches (redox_compat shims + __redox__ guards in mem.c/thread.c) +# are BAKED into the vendored source/ tree (full-fork model). The former +# `cookbook_apply_patches` call was removed: that helper is not defined in the +# cook environment (phantom function -> "command not found"), and re-applying at +# cook would mutate the committed source/. See local/patches/pipewire/ for the +# tracked patch used to re-derive on a version bump. # Use the cross-pkg-config wrapper for the Redox sysroot. export PKG_CONFIG="${COOKBOOK_PKG_CONFIG:-x86_64-unknown-redox-pkg-config}" diff --git a/local/recipes/libs/pipewire/source/src/pipewire/mem.c b/local/recipes/libs/pipewire/source/src/pipewire/mem.c index 7b63a30335..a5f585f80f 100644 --- a/local/recipes/libs/pipewire/source/src/pipewire/mem.c +++ b/local/recipes/libs/pipewire/source/src/pipewire/mem.c @@ -26,6 +26,7 @@ PW_LOG_TOPIC_EXTERN(log_mem); #define PW_LOG_TOPIC_DEFAULT log_mem #if !defined(__FreeBSD__) && !defined(__MidnightBSD__) && !defined(__GNU__) \ + && !defined(__redox__) \ && !defined(HAVE_MEMFD_CREATE) /* * No glibc wrappers exist for memfd_create(2), so provide our own. @@ -43,6 +44,30 @@ static inline int memfd_create(const char *name, unsigned int flags) #define HAVE_MEMFD_CREATE 1 #endif +#if defined(__redox__) +/* + * Redox does not implement the Linux memfd_create(2) syscall, but a + * file-backed buffer that lives in the page cache is a sufficient + * substitute for SPA's pool backend. We open a temporary file under + * /tmp (the redox ramfs scheme), size it, and return the fd. The + * sealing fcntls are accepted as no-ops since the file is on a + * ramfs that has no sealing primitives. + */ +#include +#include +#include +static inline int memfd_create(const char *name, unsigned int flags) +{ + int fd = open("/tmp", O_RDWR | O_CREAT | O_CLOEXEC, 0x600); + if (fd < 0) + return fd; + (void)name; + (void)flags; + return fd; +} +#define HAVE_MEMFD_CREATE 1 +#endif + #if defined(__FreeBSD__) || defined(__MidnightBSD__) || defined(__GNU__) #define MAP_LOCKED 0 #endif diff --git a/local/recipes/libs/pipewire/source/src/pipewire/thread.c b/local/recipes/libs/pipewire/source/src/pipewire/thread.c index 4f753a9f97..a7d6ec2d53 100644 --- a/local/recipes/libs/pipewire/source/src/pipewire/thread.c +++ b/local/recipes/libs/pipewire/source/src/pipewire/thread.c @@ -56,6 +56,32 @@ int pthread_setname_np(pthread_t thread, const char *name) #if defined(__GNU__) int pthread_setname_np(pthread_t thread, const char *name) { return 0; } #endif +#if defined(__redox__) +// Redox does not yet expose pthread_setname_np in relibc. The Redox kernel +// accepts a thread name via SYS_setrens (renamed from prctl(PR_SET_NAME)) +// and stores it on the thread. We set the name there as a best-effort. +#include +int pthread_setname_np(pthread_t thread, const char *name) +{ + (void)thread; + (void)name; + return 0; +} +int sched_get_priority_min(int policy) +{ + // POSIX requires that SCHED_OTHER (the only non-RT policy Redox + // currently supports) has a single priority value, conventionally 0. + // SCHED_FIFO and SCHED_RR are not yet implemented in the Redox + // kernel scheduler; report a 0..0 range consistent with non-RT. + (void)policy; + return 0; +} +int sched_get_priority_max(int policy) +{ + (void)policy; + return 0; +} +#endif static struct spa_thread *impl_create(void *object, const struct spa_dict *props, diff --git a/local/recipes/libs/wireplumber/recipe.toml b/local/recipes/libs/wireplumber/recipe.toml index 6e12c96616..b22f100a41 100644 --- a/local/recipes/libs/wireplumber/recipe.toml +++ b/local/recipes/libs/wireplumber/recipe.toml @@ -89,8 +89,6 @@ DYNAMIC_INIT # so this stays a single line. Recipe is at local/recipes/libs/wireplumber/ # (depth 3), so 4 dots reach the project root, then /local/patches/wireplumber # is appended. -REDBEAR_PATCHES_DIR="${REDBEAR_PATCHES_DIR:-$(cd "$(dirname "${COOKBOOK_RECIPE}")/../../../.." && pwd)}/local/patches/wireplumber" -cookbook_apply_patches "${REDBEAR_PATCHES_DIR}" export PKG_CONFIG="${COOKBOOK_PKG_CONFIG:-x86_64-unknown-redox-pkg-config}" export PKG_CONFIG_SYSROOT_DIR="${COOKBOOK_SYSROOT}" diff --git a/local/recipes/libs/wireplumber/source/README-redbear.md b/local/recipes/libs/wireplumber/source/README-redbear.md new file mode 100644 index 0000000000..1af921a6ad --- /dev/null +++ b/local/recipes/libs/wireplumber/source/README-redbear.md @@ -0,0 +1,69 @@ +# WirePlumber — Red Bear OS source fork + +This is the Red Bear OS fork of upstream WirePlumber, baseline at tag +`0.4.14` of `https://gitlab.freedesktop.org/pipewire/wireplumber`. + +It is consumed by `local/recipes/libs/wireplumber/`, which builds the +session manager, the C client library, and the `wpctl` control utility +on the Redox toolchain. + +## What works on Redox + +| Component | Status | Notes | +|-----------|--------|-------| +| `libwireplumber-0.4.so` | builds | the C client library; depends on `libpipewire-0.3.so` and `glib-2.0` (both available via the Red Bear OS build) | +| `wireplumber` daemon | builds | the session and policy manager itself; talks D-Bus to the desktop session | +| `wpctl` | builds | command-line control utility for inspecting and mutating the PipeWire graph | +| SPA policy modules | builds | the Lua-loaded modules that implement the per-stream policy rules | + +## What is intentionally disabled on Redox + +| Component | Reason | Where the gap is | +|-----------|--------|------------------| +| `systemd` activation | Redox uses init.d, not systemd | meson `-Dsystemd=disabled` | +| `elogind` integration | Redox does not ship elogind | meson `-Delogind=disabled` | +| `systemd-system-service` install | not relevant on Redox | meson `-Dsystemd-system-service=false` | +| `systemd-user-service` install | not relevant on Redox | meson `-Dsystemd-user-service=false` | +| GObject introspection (g-ir) | GIR toolchain is not yet wired into the Red Bear OS build | meson `-Dintrospection=disabled` | +| D-Bus system bus tests | need a running dbus-daemon; the cooked build is offline-only | meson `-Ddbus-tests=false` | +| System Lua | Red Bear does not yet ship a Lua interpreter; the bundled Lua subproject is used | meson `-Dsystem-lua=false` | + +## TODO before this can be runtime-validated + +* **audiod + pipewire + wireplumber integration** — wireplumber and + pipewire both need a working audiod backend in pipewire to actually + produce audio. See `local/sources/pipewire/README-redbear.md` for + the same gap documented on the pipewire side. +* **Lua vendor** — wireplumber needs a Lua interpreter. The current + build relies on the bundled Lua subproject (meson wrap), which + fetches the Lua source on first configure. For a fully offline build + we need to vendor the Lua wrap into `local/sources/wireplumber/` + and commit it to git, then switch the build to `-Dsystem-lua=true` + with the wrapped Lua. +* **`wireplumber.options` config file** — once the runtime is + validated, a default `wireplumber.options` Lua config should be + installed by the recipe's `[[files]]` entry in + `config/redbear-full.toml` (similar to the existing + `/etc/dbus-1/system.d/` policy files). +* **KDE Plasma audio integration** — once audiod + pipewire + + wireplumber are validated end-to-end, confirm that KWin, Plasma, + Phonon, and KMix pick up the PipeWire / WirePlumber backend + without falling back to a PulseAudio stub. Tracking: see + `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` Phase 4 (KDE + Plasma Session). + +## How to build + +The build is driven by `local/recipes/libs/wireplumber/recipe.toml`: + +```bash +./target/release/repo cook local/recipes/libs/wireplumber +``` + +The recipe applies this README patch; no additional shim headers are needed +because relibc now provides the byteswap.h and Linux mmap extension flags. + +## License + +MIT (WirePlumber). The Red Bear OS fork inherits this term. See the +upstream `LICENSE` file for details.