From a82eeec90304544b3488695a4cd55912c751e38b Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 01/25] =?UTF-8?q?wallpaper:=20add=20nonos=5Ftoolkit=20dep?= =?UTF-8?q?=20for=20decode=5Fclient=20=E2=80=94=20Cargo.toml=20[planA-port?= =?UTF-8?q?]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/userland/capsule_wallpaper/Cargo.toml b/userland/capsule_wallpaper/Cargo.toml index 30de1154f..0ff52aa1c 100644 --- a/userland/capsule_wallpaper/Cargo.toml +++ b/userland/capsule_wallpaper/Cargo.toml @@ -24,6 +24,7 @@ path = "src/main.rs" [dependencies] nonos_libc = { package = "nonos_userland_libc", path = "../libc" } +nonos_toolkit = { path = "../toolkit" } [profile.release] panic = "abort" From a66d1d439329764de2222e27d15f2537cdf36736 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 02/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/main.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/src/main.rs | 83 +++++--------------------- 1 file changed, 15 insertions(+), 68 deletions(-) diff --git a/userland/capsule_wallpaper/src/main.rs b/userland/capsule_wallpaper/src/main.rs index 18c1bc00b..af7001683 100644 --- a/userland/capsule_wallpaper/src/main.rs +++ b/userland/capsule_wallpaper/src/main.rs @@ -17,80 +17,27 @@ #![no_std] #![no_main] -use nonos_libc::{ - mk_debug, mk_exit, nonos_display_dimensions, nonos_surface_create, nonos_surface_destroy, - nonos_surface_map, nonos_surface_present_full, NONOS_PIXEL_FMT_ARGB8888, -}; +extern crate alloc; -const SOLID_ARGB: u32 = 0xFF20_2030; -const ENOTSUP: i64 = -95; +mod compositor_client; +mod decode_client; +mod debug; +mod paint; +mod protocol; +mod server; +mod setup; +mod state; -fn marker(stage: &[u8]) { - let mut buf = [0u8; 64]; - let prefix = b"[wallpaper] "; - let mut n = 0usize; - let cap = buf.len() - 1; - for &b in prefix.iter().chain(stage.iter()) { - if n >= cap { - break; - } - buf[n] = b; - n += 1; - } - buf[n] = b'\n'; - n += 1; - let _ = mk_debug(buf.as_ptr(), n); -} +use nonos_libc::{heap_init, mk_exit}; #[no_mangle] pub unsafe extern "C" fn _start() -> ! { - let mut w: u32 = 0; - let mut h: u32 = 0; - let rc = nonos_display_dimensions(0, &mut w as *mut u32, &mut h as *mut u32); - if rc == ENOTSUP { - marker(b"graphics parked"); - marker(b"PASS"); - mk_exit(0); - } - if rc != 0 || w == 0 || h == 0 { - marker(b"FAIL display_dimensions"); + if heap_init().is_err() { mk_exit(1); } - marker(b"display ok"); - - let id = nonos_surface_create(w, h, NONOS_PIXEL_FMT_ARGB8888); - if id < 0 { - marker(b"FAIL surface_create"); + let Ok(ctx) = setup::run() else { + debug::marker(b"setup failed"); mk_exit(2); - } - marker(b"surface created"); - - let base = nonos_surface_map(id as u64); - if base.is_null() { - marker(b"FAIL surface_map"); - let _ = nonos_surface_destroy(id as u64); - mk_exit(3); - } - let pixels = base as *mut u32; - let count = (w as usize) * (h as usize); - for i in 0..count { - core::ptr::write_volatile(pixels.add(i), SOLID_ARGB); - } - marker(b"surface filled"); - - let prc = nonos_surface_present_full(0, id as u64); - if prc != 0 { - marker(b"FAIL surface_present"); - let _ = nonos_surface_destroy(id as u64); - mk_exit(4); - } - marker(b"present ok"); - - let drc = nonos_surface_destroy(id as u64); - if drc != 0 { - marker(b"FAIL surface_destroy"); - mk_exit(5); - } - marker(b"PASS"); - mk_exit(0) + }; + server::run(ctx); } From b6e02d88979a0e5298ce6aa7fc7ff4a52b949d3b Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 03/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/server/handlers/fade.rs=20[planA-?= =?UTF-8?q?port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/src/server/handlers/fade.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/userland/capsule_wallpaper/src/server/handlers/fade.rs b/userland/capsule_wallpaper/src/server/handlers/fade.rs index a80d61386..2ca447497 100644 --- a/userland/capsule_wallpaper/src/server/handlers/fade.rs +++ b/userland/capsule_wallpaper/src/server/handlers/fade.rs @@ -16,6 +16,8 @@ use nonos_libc::mk_display_vsync_wait; +use crate::compositor_client::push_damage_commit; +use crate::paint::fill_argb; use crate::protocol::{Request, E_INVAL, FADE_REQ_LEN}; use crate::server::respond; use crate::state::Context; @@ -35,5 +37,12 @@ pub fn handle(ctx: &mut Context, sender_pid: u32, req: &Request, body: &[u8], tx let now_ns = if now > 0 { now as u64 } else { 0 }; let duration_ns = (duration_ms as u64).saturating_mul(1_000_000); ctx.fade.start(ctx.alpha, target_alpha as u8, now_ns, duration_ns); + if duration_ns == 0 { + ctx.alpha = target_alpha as u8; + let argb = ctx.current_argb(); + fill_argb(ctx.backing_va, ctx.stride, ctx.width, ctx.height, argb); + let rid = ctx.issue_request_id(); + let _ = push_damage_commit(ctx.compositor_port, rid, 0, 0, ctx.width, ctx.height); + } let _ = respond::status(sender_pid, req, 0, tx); } From b61c7d6346e7e0799994cdb23772511581f7b21f Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 04/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/server/handlers/get=5Fwallpaper.r?= =?UTF-8?q?s=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/src/server/handlers/get_wallpaper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/userland/capsule_wallpaper/src/server/handlers/get_wallpaper.rs b/userland/capsule_wallpaper/src/server/handlers/get_wallpaper.rs index 142f21741..431651a72 100644 --- a/userland/capsule_wallpaper/src/server/handlers/get_wallpaper.rs +++ b/userland/capsule_wallpaper/src/server/handlers/get_wallpaper.rs @@ -20,7 +20,7 @@ use crate::state::Context; pub fn handle(ctx: &Context, sender_pid: u32, req: &Request, tx: &mut [u8]) { let off = HDR_LEN + STATUS_LEN; - tx[off..off + 4].copy_from_slice(&ctx.argb.to_le_bytes()); + tx[off..off + 4].copy_from_slice(&ctx.current_argb().to_le_bytes()); tx[off + 4..off + 8].copy_from_slice(&ctx.policy.as_u32().to_le_bytes()); tx[off + 8..off + 12].copy_from_slice(&ctx.width.to_le_bytes()); tx[off + 12..off + 16].copy_from_slice(&ctx.height.to_le_bytes()); From 3a8e415fec3c41da8a51e7f92d2a14c279ce79d4 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 05/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/server/handlers/set=5Fpolicy.rs?= =?UTF-8?q?=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/src/server/handlers/set_policy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/userland/capsule_wallpaper/src/server/handlers/set_policy.rs b/userland/capsule_wallpaper/src/server/handlers/set_policy.rs index bbf995ede..fb8b9e19e 100644 --- a/userland/capsule_wallpaper/src/server/handlers/set_policy.rs +++ b/userland/capsule_wallpaper/src/server/handlers/set_policy.rs @@ -28,6 +28,6 @@ pub fn handle(ctx: &mut Context, sender_pid: u32, req: &Request, body: &[u8], tx let _ = respond::status(sender_pid, req, E_INVAL, tx); return; }; - ctx.policy = policy; + ctx.set_policy(policy); let _ = respond::status(sender_pid, req, 0, tx); } From 689917d74bdd6b02b099cec813ebaff6df0accda Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 06/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/server/handlers/set=5Fwallpaper.r?= =?UTF-8?q?s=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/server/handlers/set_wallpaper.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/userland/capsule_wallpaper/src/server/handlers/set_wallpaper.rs b/userland/capsule_wallpaper/src/server/handlers/set_wallpaper.rs index 2463b3765..28f8d2ab0 100644 --- a/userland/capsule_wallpaper/src/server/handlers/set_wallpaper.rs +++ b/userland/capsule_wallpaper/src/server/handlers/set_wallpaper.rs @@ -15,21 +15,22 @@ // along with this program. If not, see . use crate::compositor_client::push_damage_commit; +use crate::decode_client::decode_and_paint; use crate::paint::fill_argb; use crate::protocol::{Request, E_INVAL, SET_WALLPAPER_REQ_LEN}; use crate::server::respond; use crate::state::Context; pub fn handle(ctx: &mut Context, sender_pid: u32, req: &Request, body: &[u8], tx: &mut [u8]) { - if body.len() != SET_WALLPAPER_REQ_LEN { + if body.len() == SET_WALLPAPER_REQ_LEN { + let argb = u32::from_le_bytes(body[0..4].try_into().unwrap()); + ctx.set_argb(argb); + let composed = ctx.current_argb(); + fill_argb(ctx.backing_va, ctx.stride, ctx.width, ctx.height, composed); + } else if decode_and_paint(ctx, body).is_err() { let _ = respond::status(sender_pid, req, E_INVAL, tx); return; } - let argb = u32::from_le_bytes(body[0..4].try_into().unwrap()); - ctx.argb = argb; - ctx.alpha = (argb >> 24) as u8; - let composed = ctx.current_argb(); - fill_argb(ctx.backing_va, ctx.stride, ctx.width, ctx.height, composed); let rid = ctx.issue_request_id(); let _ = push_damage_commit(ctx.compositor_port, rid, 0, 0, ctx.width, ctx.height); let _ = respond::status(sender_pid, req, 0, tx); From c269b3313e2be769b32fae99cf15d8fe6913867f Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 07/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/setup/discover.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capsule_wallpaper/src/setup/discover.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/userland/capsule_wallpaper/src/setup/discover.rs b/userland/capsule_wallpaper/src/setup/discover.rs index f6a2c710c..f6d58401e 100644 --- a/userland/capsule_wallpaper/src/setup/discover.rs +++ b/userland/capsule_wallpaper/src/setup/discover.rs @@ -17,18 +17,27 @@ use nonos_libc::mk_service_lookup; const COMPOSITOR_SERVICE: &[u8] = b"compositor"; +const DESKTOP_SHELL_SERVICE: &[u8] = b"desktop_shell"; -pub fn lookup_compositor_port() -> Result { +fn lookup_port(name: &[u8]) -> Result { let mut pid: u32 = 0; let mut port: u32 = 0; let rc = mk_service_lookup( - COMPOSITOR_SERVICE.as_ptr(), - COMPOSITOR_SERVICE.len(), + name.as_ptr(), + name.len(), &mut port as *mut u32, &mut pid as *mut u32, ); if rc < 0 || pid == 0 || port == 0 { - return Err("compositor service not announced"); + return Err("service not announced"); } Ok(port) } + +pub fn lookup_compositor_port() -> Result { + lookup_port(COMPOSITOR_SERVICE).map_err(|_| "compositor service not announced") +} + +pub fn lookup_desktop_shell_port() -> Result { + lookup_port(DESKTOP_SHELL_SERVICE).map_err(|_| "desktop_shell service not announced") +} From d15b35dadc607db34a259240db6a7fed331ce153 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:46 +0600 Subject: [PATCH 08/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/setup/prime.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/src/setup/prime.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/userland/capsule_wallpaper/src/setup/prime.rs b/userland/capsule_wallpaper/src/setup/prime.rs index 3cd9087e6..72c163ee1 100644 --- a/userland/capsule_wallpaper/src/setup/prime.rs +++ b/userland/capsule_wallpaper/src/setup/prime.rs @@ -31,6 +31,7 @@ const BOTTOM_Z: u32 = 0; pub fn run() -> Result { let compositor_port = discover::lookup_compositor_port()?; + let _ = discover::lookup_desktop_shell_port()?; let mut width: u32 = 0; let mut height: u32 = 0; let rc = nonos_display_dimensions(0, &mut width as *mut u32, &mut height as *mut u32); @@ -83,6 +84,7 @@ pub fn run() -> Result { fade: FadeTimeline::new(), next_request_id: 1, }; + ctx.set_argb(DEFAULT_ARGB); let rid = ctx.issue_request_id(); push_scene_submit(compositor_port, rid, handle as u64, 0, 0, width, height, BOTTOM_Z)?; Ok(ctx) From 390e4c77478f67d59df2ea5f5e5b83214b1e0abd Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:47 +0600 Subject: [PATCH 09/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20feat()=20ser?= =?UTF-8?q?vice=20path=20=E2=80=94=20src/state/context.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/src/state/context.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/userland/capsule_wallpaper/src/state/context.rs b/userland/capsule_wallpaper/src/state/context.rs index 6913c101c..3dc195778 100644 --- a/userland/capsule_wallpaper/src/state/context.rs +++ b/userland/capsule_wallpaper/src/state/context.rs @@ -36,6 +36,15 @@ impl Context { id } + pub fn set_argb(&mut self, argb: u32) { + self.argb = argb; + self.alpha = (argb >> 24) as u8; + } + + pub fn set_policy(&mut self, policy: Policy) { + self.policy = policy; + } + pub fn current_argb(&self) -> u32 { let rgb = self.argb & 0x00FF_FFFF; ((self.alpha as u32) << 24) | rgb From f9d238a69e557c7e45aa48e42fdba0631916fdcc Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:47 +0600 Subject: [PATCH 10/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20image=20deco?= =?UTF-8?q?de=5Fclient=20=E2=80=94=20src/decode=5Fclient/header.rs=20[plan?= =?UTF-8?q?A-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/decode_client/header.rs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 userland/capsule_wallpaper/src/decode_client/header.rs diff --git a/userland/capsule_wallpaper/src/decode_client/header.rs b/userland/capsule_wallpaper/src/decode_client/header.rs new file mode 100644 index 000000000..70463caa4 --- /dev/null +++ b/userland/capsule_wallpaper/src/decode_client/header.rs @@ -0,0 +1,55 @@ +// NONOS Operating System +// Copyright (C) 2026 NONOS Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use crate::protocol::E_INVAL; + +pub const DECODE_HDR_LEN: usize = 16; + +#[derive(Clone, Copy)] +pub enum DecodeKind { + Png, + Bmp, + Lz4Raw, + Jpeg, +} + +pub struct DecodeReq<'a> { + pub kind: DecodeKind, + pub width: u32, + pub height: u32, + pub payload: &'a [u8], +} + +pub fn parse_decode_req(body: &[u8]) -> Result, i32> { + if body.len() < DECODE_HDR_LEN { + return Err(E_INVAL); + } + let kind_raw = u32::from_le_bytes(body[0..4].try_into().unwrap()); + let width = u32::from_le_bytes(body[4..8].try_into().unwrap()); + let height = u32::from_le_bytes(body[8..12].try_into().unwrap()); + let payload_len = u32::from_le_bytes(body[12..16].try_into().unwrap()) as usize; + if body.len() != DECODE_HDR_LEN + payload_len { + return Err(E_INVAL); + } + let kind = match kind_raw { + 1 => DecodeKind::Png, + 2 => DecodeKind::Bmp, + 3 => DecodeKind::Lz4Raw, + 4 => DecodeKind::Jpeg, + _ => return Err(E_INVAL), + }; + Ok(DecodeReq { kind, width, height, payload: &body[DECODE_HDR_LEN..] }) +} From 36c9dd6caf5fce0b4afc2e0b439b6b3f9852ff36 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:47 +0600 Subject: [PATCH 11/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20image=20deco?= =?UTF-8?q?de=5Fclient=20=E2=80=94=20src/decode=5Fclient/mod.rs=20[planA-p?= =?UTF-8?q?ort]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/decode_client/mod.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 userland/capsule_wallpaper/src/decode_client/mod.rs diff --git a/userland/capsule_wallpaper/src/decode_client/mod.rs b/userland/capsule_wallpaper/src/decode_client/mod.rs new file mode 100644 index 000000000..2f1deaf83 --- /dev/null +++ b/userland/capsule_wallpaper/src/decode_client/mod.rs @@ -0,0 +1,21 @@ +// NONOS Operating System +// Copyright (C) 2026 NONOS Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +pub mod header; +pub mod seq; +pub mod wire; + +pub use seq::decode_and_paint; From 195aef3070f7097ad45a8f3fc903cfd00c82a003 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:47 +0600 Subject: [PATCH 12/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20image=20deco?= =?UTF-8?q?de=5Fclient=20=E2=80=94=20src/decode=5Fclient/seq.rs=20[planA-p?= =?UTF-8?q?ort]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/decode_client/seq.rs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 userland/capsule_wallpaper/src/decode_client/seq.rs diff --git a/userland/capsule_wallpaper/src/decode_client/seq.rs b/userland/capsule_wallpaper/src/decode_client/seq.rs new file mode 100644 index 000000000..edc105ee6 --- /dev/null +++ b/userland/capsule_wallpaper/src/decode_client/seq.rs @@ -0,0 +1,60 @@ +// NONOS Operating System +// Copyright (C) 2026 NONOS Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use alloc::vec; + +use super::{header::parse_decode_req, wire::decode_argb}; +use crate::{protocol::E_INVAL, state::Context}; + +pub fn decode_and_paint(ctx: &Context, body: &[u8]) -> Result<(), i32> { + let req = parse_decode_req(body)?; + let cap = (ctx.width as usize).saturating_mul(ctx.height as usize); + let mut decoded = vec![0u32; cap]; + let size = decode_argb(&req, &mut decoded).map_err(|_| E_INVAL)?; + paint_stretch( + ctx.backing_va, + ctx.stride as usize, + ctx.width as usize, + ctx.height as usize, + &decoded, + size.width as usize, + size.height as usize, + ); + Ok(()) +} + +fn paint_stretch( + base_va: u64, + stride: usize, + dst_w: usize, + dst_h: usize, + src: &[u32], + src_w: usize, + src_h: usize, +) { + if src_w == 0 || src_h == 0 || dst_w == 0 || dst_h == 0 { + return; + } + for y in 0..dst_h { + let sy = (y * src_h) / dst_h; + for x in 0..dst_w { + let sx = (x * src_w) / dst_w; + let px = src[sy * src_w + sx]; + let addr = (base_va as usize + y * stride + x * 4) as *mut u32; + unsafe { core::ptr::write_volatile(addr, px) }; + } + } +} From a3e3c2cf6719043b598491fbe7d676fd980d9dc7 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:52:47 +0600 Subject: [PATCH 13/25] =?UTF-8?q?wallpaper:=20port=20plan-a=20image=20deco?= =?UTF-8?q?de=5Fclient=20=E2=80=94=20src/decode=5Fclient/wire.rs=20[planA-?= =?UTF-8?q?port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/decode_client/wire.rs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 userland/capsule_wallpaper/src/decode_client/wire.rs diff --git a/userland/capsule_wallpaper/src/decode_client/wire.rs b/userland/capsule_wallpaper/src/decode_client/wire.rs new file mode 100644 index 000000000..e651b81cd --- /dev/null +++ b/userland/capsule_wallpaper/src/decode_client/wire.rs @@ -0,0 +1,34 @@ +// NONOS Operating System +// Copyright (C) 2026 NONOS Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use nonos_toolkit::image::{ + bmp::decode_bmp_argb8888, + jpeg::decode_jpeg_argb8888, + lz4_raw::decode_lz4_raw_argb8888, + png::decoder::decode_png_argb8888, + types::{DecodeError, ImageSize}, +}; + +use super::header::{DecodeKind, DecodeReq}; + +pub fn decode_argb(req: &DecodeReq<'_>, out: &mut [u32]) -> Result { + match req.kind { + DecodeKind::Png => decode_png_argb8888(req.payload, out), + DecodeKind::Bmp => decode_bmp_argb8888(req.payload, out), + DecodeKind::Lz4Raw => decode_lz4_raw_argb8888(req.width, req.height, req.payload, out), + DecodeKind::Jpeg => decode_jpeg_argb8888(req.payload, out), + } +} From 38a3d23acaeb84ef551fcbadc167f7eb1f1f03cb Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:53:04 +0600 Subject: [PATCH 14/25] =?UTF-8?q?wallpaper:=20lockfile=20for=20nonos=5Ftoo?= =?UTF-8?q?lkit=20dep=20=E2=80=94=20Cargo.lock=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_wallpaper/Cargo.lock | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/userland/capsule_wallpaper/Cargo.lock b/userland/capsule_wallpaper/Cargo.lock index c12eceb28..8a3c966e9 100644 --- a/userland/capsule_wallpaper/Cargo.lock +++ b/userland/capsule_wallpaper/Cargo.lock @@ -23,6 +23,14 @@ dependencies = [ [[package]] name = "nonos_capsule_wallpaper" version = "0.1.0" +dependencies = [ + "nonos_toolkit", + "nonos_userland_libc", +] + +[[package]] +name = "nonos_toolkit" +version = "0.1.0" dependencies = [ "nonos_userland_libc", ] From f2d1fa56968d8be4111f6993460c22fffa4bf0ca Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:40 +0600 Subject: [PATCH 15/25] =?UTF-8?q?desktop=5Fshell:=20drop=20file=20supersed?= =?UTF-8?q?ed=20by=20plan-a=20feat()=20architecture=20=E2=80=94=20src/comp?= =?UTF-8?q?ositor=5Fclient/health.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/compositor_client/health.rs | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 userland/capsule_desktop_shell/src/compositor_client/health.rs diff --git a/userland/capsule_desktop_shell/src/compositor_client/health.rs b/userland/capsule_desktop_shell/src/compositor_client/health.rs deleted file mode 100644 index 85270b4ca..000000000 --- a/userland/capsule_desktop_shell/src/compositor_client/health.rs +++ /dev/null @@ -1,27 +0,0 @@ -// NONOS Operating System -// Copyright (C) 2026 NONOS Contributors -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use super::wire::call; - -const OP: u16 = 0x0001; - -pub fn probe(compositor_port: u32, request_id: u32) -> Result<(), &'static str> { - let status = call(compositor_port, OP, request_id, &[])?; - if status != 0 { - return Err("compositor health rejected"); - } - Ok(()) -} From ee75d1db06bfd478e073e98d5ea0f991244d8189 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 16/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20service=20path=20=E2=80=94=20src/compositor=5Fclient/mod.rs?= =?UTF-8?q?=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_desktop_shell/src/compositor_client/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/userland/capsule_desktop_shell/src/compositor_client/mod.rs b/userland/capsule_desktop_shell/src/compositor_client/mod.rs index f8a61ae0d..89ac53295 100644 --- a/userland/capsule_desktop_shell/src/compositor_client/mod.rs +++ b/userland/capsule_desktop_shell/src/compositor_client/mod.rs @@ -15,10 +15,8 @@ // along with this program. If not, see . pub mod damage_commit; -pub mod health; pub mod scene_submit; pub mod wire; pub use damage_commit::push_damage_commit; -pub use health::probe as probe_compositor; pub use scene_submit::push_scene_submit; From bcdb5e463199dcafad05ef30280ea86236ad0b85 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 17/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20service=20path=20=E2=80=94=20src/main.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_desktop_shell/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/userland/capsule_desktop_shell/src/main.rs b/userland/capsule_desktop_shell/src/main.rs index 127e07639..13b68670b 100644 --- a/userland/capsule_desktop_shell/src/main.rs +++ b/userland/capsule_desktop_shell/src/main.rs @@ -21,11 +21,14 @@ extern crate alloc; mod compositor_client; mod debug; +mod market_client; mod protocol; mod render; mod server; mod setup; mod state; +mod wallpaper_client; +mod wm_client; use nonos_libc::{heap_init, mk_exit}; From 9be5acf282c1cb65d3ec4bf809513e345952db37 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 18/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20=E2=80=94=20src/market=5Fclient/mod.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/market_client/mod.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 userland/capsule_desktop_shell/src/market_client/mod.rs diff --git a/userland/capsule_desktop_shell/src/market_client/mod.rs b/userland/capsule_desktop_shell/src/market_client/mod.rs new file mode 100644 index 000000000..d043ce38d --- /dev/null +++ b/userland/capsule_desktop_shell/src/market_client/mod.rs @@ -0,0 +1,31 @@ +use alloc::vec; +use alloc::vec::Vec; + +use nonos_libc::mk_ipc_call; + +const MAGIC: u32 = 0x4E4D_4B54; +const VERSION: u16 = 1; +const HDR_LEN: usize = 20; +const STATUS_LEN: usize = 4; +const OP_HEALTHCHECK: u16 = 0x0006; + +pub fn healthcheck(port: u32, request_id: u32) -> Result { + if port == 0 { + return Ok(0); + } + let mut tx = Vec::with_capacity(HDR_LEN); + tx.extend_from_slice(&MAGIC.to_le_bytes()); + tx.extend_from_slice(&VERSION.to_le_bytes()); + tx.extend_from_slice(&OP_HEALTHCHECK.to_le_bytes()); + tx.extend_from_slice(&0u16.to_le_bytes()); + tx.extend_from_slice(&0u16.to_le_bytes()); + tx.extend_from_slice(&request_id.to_le_bytes()); + tx.extend_from_slice(&0u32.to_le_bytes()); + + let mut rx = vec![0u8; HDR_LEN + STATUS_LEN]; + let rc = mk_ipc_call(port as u64, tx.as_ptr(), tx.len(), rx.as_mut_ptr(), rx.len()); + if rc < (HDR_LEN + STATUS_LEN) as i64 { + return Err("market call failed"); + } + Ok(i32::from_le_bytes(rx[HDR_LEN..HDR_LEN + STATUS_LEN].try_into().unwrap())) +} From 2075b7df780ec5234ac0bc5b091565203c34d1df Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 19/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20service=20path=20=E2=80=94=20src/setup/discover.rs=20[planA-?= =?UTF-8?q?port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/setup/discover.rs | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/userland/capsule_desktop_shell/src/setup/discover.rs b/userland/capsule_desktop_shell/src/setup/discover.rs index 2d42bc282..3a87d489b 100644 --- a/userland/capsule_desktop_shell/src/setup/discover.rs +++ b/userland/capsule_desktop_shell/src/setup/discover.rs @@ -17,18 +17,37 @@ use nonos_libc::mk_service_lookup; const COMPOSITOR_SERVICE: &[u8] = b"compositor"; +const WM_SERVICE: &[u8] = b"wm"; +const WALLPAPER_SERVICE: &[u8] = b"wallpaper"; +const MARKET_SERVICE: &[u8] = b"market.index"; -pub fn require_compositor() -> Result { +fn lookup_port(name: &[u8]) -> Result { let mut pid: u32 = 0; let mut port: u32 = 0; let rc = mk_service_lookup( - COMPOSITOR_SERVICE.as_ptr(), - COMPOSITOR_SERVICE.len(), + name.as_ptr(), + name.len(), &mut port as *mut u32, &mut pid as *mut u32, ); if rc < 0 || pid == 0 || port == 0 { - return Err("compositor service not announced"); + return Err("service not announced"); } Ok(port) } + +pub fn require_compositor() -> Result { + lookup_port(COMPOSITOR_SERVICE).map_err(|_| "compositor service not announced") +} + +pub fn require_wm() -> Result { + lookup_port(WM_SERVICE).map_err(|_| "wm service not announced") +} + +pub fn require_wallpaper() -> Result { + lookup_port(WALLPAPER_SERVICE).map_err(|_| "wallpaper service not announced") +} + +pub fn try_market() -> u32 { + lookup_port(MARKET_SERVICE).unwrap_or(0) +} From 76eff2b556b0ac47bf785b51d77e8140493c66c9 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 20/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20service=20path=20=E2=80=94=20src/setup/mod.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_desktop_shell/src/setup/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/userland/capsule_desktop_shell/src/setup/mod.rs b/userland/capsule_desktop_shell/src/setup/mod.rs index 7d87f3464..7197206f2 100644 --- a/userland/capsule_desktop_shell/src/setup/mod.rs +++ b/userland/capsule_desktop_shell/src/setup/mod.rs @@ -16,6 +16,5 @@ mod discover; mod prime; -mod retry; -pub use retry::run; +pub use prime::run; From 20fdcd4cf3aeb2dd5368f76843a3036b7ef348d0 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 21/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20service=20path=20=E2=80=94=20src/setup/prime.rs=20[planA-por?= =?UTF-8?q?t]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capsule_desktop_shell/src/setup/prime.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/userland/capsule_desktop_shell/src/setup/prime.rs b/userland/capsule_desktop_shell/src/setup/prime.rs index dc465db8e..de3af1b85 100644 --- a/userland/capsule_desktop_shell/src/setup/prime.rs +++ b/userland/capsule_desktop_shell/src/setup/prime.rs @@ -20,17 +20,22 @@ use nonos_libc::{ }; use super::discover; -use crate::compositor_client::{probe_compositor, push_scene_submit}; +use crate::compositor_client::push_scene_submit; +use crate::market_client; use crate::render::paint_chrome; use crate::state::{Context, SpotlightState, TrayTable}; +use crate::wallpaper_client; +use crate::wm_client; const PROT_READ_WRITE: i32 = 0x3; const MAP_PRIVATE_ANON: i32 = 0x22; const OVERLAY_Z: u32 = 1; -pub fn run_once() -> Result { +pub fn run() -> Result { let compositor_port = discover::require_compositor()?; - probe_compositor(compositor_port, 1)?; + let wm_port = discover::require_wm()?; + let wallpaper_port = discover::require_wallpaper()?; + let market_port = discover::try_market(); let mut width: u32 = 0; let mut height: u32 = 0; let rc = nonos_display_dimensions(0, &mut width as *mut u32, &mut height as *mut u32); @@ -55,6 +60,9 @@ pub fn run_once() -> Result { let backing_va = base as u64; let mut ctx = Context { compositor_port, + wm_port, + wallpaper_port, + market_port, width, height, stride, @@ -84,5 +92,8 @@ pub fn run_once() -> Result { } let rid = ctx.issue_request_id(); push_scene_submit(compositor_port, rid, handle as u64, 0, 0, width, height, OVERLAY_Z)?; + let _ = wm_client::healthcheck(ctx.wm_port, ctx.issue_request_id()); + let _ = wallpaper_client::set_policy(ctx.wallpaper_port, ctx.issue_request_id(), 0); + let _ = market_client::healthcheck(ctx.market_port, ctx.issue_request_id()); Ok(ctx) } From 11a3279b1cbc3474363987a13bf89a673b529cd9 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:41 +0600 Subject: [PATCH 22/25] =?UTF-8?q?desktop=5Fshell:=20drop=20file=20supersed?= =?UTF-8?q?ed=20by=20plan-a=20feat()=20architecture=20=E2=80=94=20src/setu?= =?UTF-8?q?p/retry.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capsule_desktop_shell/src/setup/retry.rs | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 userland/capsule_desktop_shell/src/setup/retry.rs diff --git a/userland/capsule_desktop_shell/src/setup/retry.rs b/userland/capsule_desktop_shell/src/setup/retry.rs deleted file mode 100644 index bbbeb6fa0..000000000 --- a/userland/capsule_desktop_shell/src/setup/retry.rs +++ /dev/null @@ -1,36 +0,0 @@ -// NONOS Operating System -// Copyright (C) 2026 NONOS Contributors -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use nonos_libc::mk_yield; - -use super::prime; -use crate::state::Context; - -const READY_ATTEMPTS: usize = 256; - -pub fn run() -> Result { - let mut last_err = "compositor unavailable"; - for _ in 0..READY_ATTEMPTS { - match prime::run_once() { - Ok(ctx) => return Ok(ctx), - Err(e) => { - last_err = e; - mk_yield(); - } - } - } - Err(last_err) -} From aa9da5f8da32df79053b606940a16fd092256019 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:42 +0600 Subject: [PATCH 23/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20service=20path=20=E2=80=94=20src/state/context.rs=20[planA-p?= =?UTF-8?q?ort]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userland/capsule_desktop_shell/src/state/context.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/userland/capsule_desktop_shell/src/state/context.rs b/userland/capsule_desktop_shell/src/state/context.rs index 8e0e6cb59..f50dfc83a 100644 --- a/userland/capsule_desktop_shell/src/state/context.rs +++ b/userland/capsule_desktop_shell/src/state/context.rs @@ -18,6 +18,9 @@ use super::{NotifyLevel, SpotlightState, TrayTable}; pub struct Context { pub compositor_port: u32, + pub wm_port: u32, + pub wallpaper_port: u32, + pub market_port: u32, pub width: u32, pub height: u32, pub stride: u32, From b3c45b15c86ef27f51f4e10f17f9a6f5228c7f54 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:42 +0600 Subject: [PATCH 24/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20=E2=80=94=20src/wallpaper=5Fclient/mod.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/wallpaper_client/mod.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 userland/capsule_desktop_shell/src/wallpaper_client/mod.rs diff --git a/userland/capsule_desktop_shell/src/wallpaper_client/mod.rs b/userland/capsule_desktop_shell/src/wallpaper_client/mod.rs new file mode 100644 index 000000000..968d37957 --- /dev/null +++ b/userland/capsule_desktop_shell/src/wallpaper_client/mod.rs @@ -0,0 +1,29 @@ +use alloc::vec; +use alloc::vec::Vec; + +use nonos_libc::mk_ipc_call; + +const MAGIC: u32 = 0x4E57_4C50; +const VERSION: u16 = 1; +const HDR_LEN: usize = 20; +const STATUS_LEN: usize = 4; +const OP_SET_POLICY: u16 = 0x0004; + +pub fn set_policy(port: u32, request_id: u32, policy: u32) -> Result { + let mut tx = Vec::with_capacity(HDR_LEN + 4); + tx.extend_from_slice(&MAGIC.to_le_bytes()); + tx.extend_from_slice(&VERSION.to_le_bytes()); + tx.extend_from_slice(&OP_SET_POLICY.to_le_bytes()); + tx.extend_from_slice(&0u16.to_le_bytes()); + tx.extend_from_slice(&0u16.to_le_bytes()); + tx.extend_from_slice(&request_id.to_le_bytes()); + tx.extend_from_slice(&4u32.to_le_bytes()); + tx.extend_from_slice(&policy.to_le_bytes()); + + let mut rx = vec![0u8; HDR_LEN + STATUS_LEN]; + let rc = mk_ipc_call(port as u64, tx.as_ptr(), tx.len(), rx.as_mut_ptr(), rx.len()); + if rc < (HDR_LEN + STATUS_LEN) as i64 { + return Err("wallpaper call failed"); + } + Ok(i32::from_le_bytes(rx[HDR_LEN..HDR_LEN + STATUS_LEN].try_into().unwrap())) +} From ff59b5f216c8d229cf68b48ea558b4c1ed994134 Mon Sep 17 00:00:00 2001 From: senseix21 Date: Mon, 18 May 2026 16:57:42 +0600 Subject: [PATCH 25/25] =?UTF-8?q?desktop=5Fshell:=20port=20plan-a=20feat()?= =?UTF-8?q?=20=E2=80=94=20src/wm=5Fclient/mod.rs=20[planA-port]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/wm_client/mod.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 userland/capsule_desktop_shell/src/wm_client/mod.rs diff --git a/userland/capsule_desktop_shell/src/wm_client/mod.rs b/userland/capsule_desktop_shell/src/wm_client/mod.rs new file mode 100644 index 000000000..4dd757025 --- /dev/null +++ b/userland/capsule_desktop_shell/src/wm_client/mod.rs @@ -0,0 +1,28 @@ +use alloc::vec; +use alloc::vec::Vec; + +use nonos_libc::mk_ipc_call; + +const MAGIC: u32 = 0x4E57_4D50; +const VERSION: u16 = 1; +const HDR_LEN: usize = 20; +const STATUS_LEN: usize = 4; +const OP_HEALTHCHECK: u16 = 0x0001; + +pub fn healthcheck(port: u32, request_id: u32) -> Result { + let mut tx = Vec::with_capacity(HDR_LEN); + tx.extend_from_slice(&MAGIC.to_le_bytes()); + tx.extend_from_slice(&VERSION.to_le_bytes()); + tx.extend_from_slice(&OP_HEALTHCHECK.to_le_bytes()); + tx.extend_from_slice(&0u16.to_le_bytes()); + tx.extend_from_slice(&0u16.to_le_bytes()); + tx.extend_from_slice(&request_id.to_le_bytes()); + tx.extend_from_slice(&0u32.to_le_bytes()); + + let mut rx = vec![0u8; HDR_LEN + STATUS_LEN]; + let rc = mk_ipc_call(port as u64, tx.as_ptr(), tx.len(), rx.as_mut_ptr(), rx.len()); + if rc < (HDR_LEN + STATUS_LEN) as i64 { + return Err("wm call failed"); + } + Ok(i32::from_le_bytes(rx[HDR_LEN..HDR_LEN + STATUS_LEN].try_into().unwrap())) +}