// veilor-os Plymouth boot splash // minimal: pure black background, centered "veilor" wordmark, single // slowly-pulsing dot underneath. no fedora f, no spinning bar. // // Plymouth script reference: https://www.freedesktop.org/wiki/Software/Plymouth/Scripts/ // ── Background: pure black ────────────────────────────────────────────── Window.SetBackgroundTopColor (0.0, 0.0, 0.0); Window.SetBackgroundBottomColor(0.0, 0.0, 0.0); screen_w = Window.GetWidth(); screen_h = Window.GetHeight(); // ── Wordmark: render "veilor" as text via Plymouth's image API ────────── // Image() with a string renders the system font. Color is white (216/255). wordmark.image = Image.Text("veilor", 0.847, 0.847, 0.847, 1.0, "Sans 28"); wordmark.sprite = Sprite(wordmark.image); wordmark.sprite.SetX((screen_w - wordmark.image.GetWidth()) / 2); wordmark.sprite.SetY((screen_h - wordmark.image.GetHeight()) / 2 - 12); wordmark.sprite.SetOpacity(0.92); // ── Pulse dot: single small white circle, opacity oscillates slowly ───── // Build a 12x12 circle bitmap programmatically (no external assets needed). dot_size = 12; dot.image = Image("dot.png"); if (!dot.image) { // Plymouth can't draw arbitrary shapes from script; if dot.png is // missing, fall back to a small text bullet which the system font // will render as a centered glyph. Keeps the theme self-contained. dot.image = Image.Text("●", 0.847, 0.847, 0.847, 1.0, "Sans 18"); } dot.sprite = Sprite(dot.image); dot.sprite.SetX((screen_w - dot.image.GetWidth()) / 2); dot.sprite.SetY((screen_h - dot.image.GetHeight()) / 2 + wordmark.image.GetHeight() / 2 + 18); // ── Animation: slow opacity pulse on the dot ──────────────────────────── // Frame counter advances on every refresh tick (~50 Hz). pulse_phase = 0; fun refresh_callback() { pulse_phase++; // 240-tick cycle ≈ 4.8 s. sin-like via fractional triangle wave. cycle = pulse_phase % 240; half = 120; if (cycle < half) ratio = cycle / half; else ratio = (240 - cycle) / half; // map 0..1 to opacity 0.25..0.95 opacity = 0.25 + ratio * 0.70; dot.sprite.SetOpacity(opacity); } Plymouth.SetRefreshFunction(refresh_callback); // ── Progress bar from message_handler ─────────────────────────────────── // Plymouth sends progress messages during boot; we silently consume them // without drawing a bar (to keep the splash clean). Override as needed. fun message_callback(text) { // intentionally silent — keep splash uncluttered. Reserved for future // status-line overlay if requested. } Plymouth.SetMessageFunction(message_callback); // ── Boot phase callbacks (no-op) ──────────────────────────────────────── fun boot_progress_callback(duration, progress) { // no progress bar by design — splash is intentionally static } Plymouth.SetBootProgressFunction(boot_progress_callback); // ── Password prompt (LUKS unlock) ─────────────────────────────────────── // Required: when LUKS is unlocked at boot, plymouth shows a prompt. // We render a minimal centered prompt under the dot. prompt.label_image = NULL; prompt.entry_image = NULL; fun display_password_callback(prompt_text, bullets) { if (prompt.label_image) prompt.label_image = NULL; if (prompt.entry_image) prompt.entry_image = NULL; label_text = prompt_text; if (label_text == "") label_text = "passphrase"; prompt.label_image = Image.Text(label_text, 0.63, 0.63, 0.63, 1.0, "Sans 12"); prompt.label_sprite = Sprite(prompt.label_image); prompt.label_sprite.SetX((screen_w - prompt.label_image.GetWidth()) / 2); prompt.label_sprite.SetY(screen_h * 0.65); bullet_text = ""; i = 0; while (i < bullets) { bullet_text += "•"; i++; } if (bullet_text == "") bullet_text = " "; prompt.entry_image = Image.Text(bullet_text, 0.847, 0.847, 0.847, 1.0, "Sans 18"); prompt.entry_sprite = Sprite(prompt.entry_image); prompt.entry_sprite.SetX((screen_w - prompt.entry_image.GetWidth()) / 2); prompt.entry_sprite.SetY(screen_h * 0.65 + 24); } Plymouth.SetDisplayPasswordFunction(display_password_callback); fun display_normal_callback() { if (prompt.label_image) { prompt.label_image = NULL; prompt.label_sprite = NULL; } if (prompt.entry_image) { prompt.entry_image = NULL; prompt.entry_sprite = NULL; } } Plymouth.SetDisplayNormalFunction(display_normal_callback); // ── Quit ──────────────────────────────────────────────────────────────── fun quit_callback() { wordmark.sprite.SetOpacity(0); dot.sprite.SetOpacity(0); } Plymouth.SetQuitFunction(quit_callback);