From fcf8ae1e0b21c062ca79f14a4d76fd66403cbfee Mon Sep 17 00:00:00 2001 From: Daniel Hammer Date: Sun, 5 Jul 2026 11:34:27 +0200 Subject: [PATCH] feat: add Power GUI app (powermgr) --- kernel/src/Api/BuildNo.hpp | 2 +- programs/GNUmakefile | 13 +- programs/src/powermgr/Makefile | 77 ++++ programs/src/powermgr/main.cpp | 373 ++++++++++++++++++++ programs/src/powermgr/manifest.toml | 11 + programs/src/powermgr/stb_truetype_impl.cpp | 33 ++ scripts/install_apps.sh | 1 + 7 files changed, 505 insertions(+), 5 deletions(-) create mode 100644 programs/src/powermgr/Makefile create mode 100644 programs/src/powermgr/main.cpp create mode 100644 programs/src/powermgr/manifest.toml create mode 100644 programs/src/powermgr/stb_truetype_impl.cpp diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index b2a8a87..b148ae7 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 14 +#define MONTAUK_BUILD_NUMBER 17 diff --git a/programs/GNUmakefile b/programs/GNUmakefile index ee07512..e74da1e 100644 --- a/programs/GNUmakefile +++ b/programs/GNUmakefile @@ -59,7 +59,7 @@ BINDIR := bin PROGRAMS := $(notdir $(wildcard src/*)) # Programs with custom Makefiles (built separately). -CUSTOM_BUILDS := 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr calculator desktop login shell rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs test_dialogs test_dl libloader libhello crashpad +CUSTOM_BUILDS := 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator desktop login shell rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs test_dialogs test_dl libloader libhello crashpad SYSTEM_PROGRAMS := $(filter-out $(CUSTOM_BUILDS),$(PROGRAMS)) # Build targets: system programs go to bin/os/, apps go to bin/apps//. @@ -89,9 +89,9 @@ CONFIGDIR := data/config CONFIGSRC := $(wildcard $(CONFIGDIR)/*.toml) CONFIGDST := $(patsubst $(CONFIGDIR)/%,$(BINDIR)/config/%,$(CONFIGSRC)) -.PHONY: all clean 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr calculator login desktop shell rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs icons fonts configs bearssl libc tls libjpeg libjpegwrite install-apps libloader libs libhello test_dialogs test_dl crashpad check-syscalls gen-syscalls +.PHONY: all clean 2048 doom fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator login desktop shell rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs icons fonts configs bearssl libc tls libjpeg libjpegwrite install-apps libloader libs libhello test_dialogs test_dl crashpad check-syscalls gen-syscalls -all: bearssl libc libjpeg libjpegwrite tls libloader libs libhello $(TARGETS) fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr calculator 2048 doom rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell icons fonts install-apps test_dialogs test_dl crashpad $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(FWDST) +all: bearssl libc libjpeg libjpegwrite tls libloader libs libhello $(TARGETS) fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator 2048 doom rpgdemo paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell icons fonts install-apps test_dialogs test_dl crashpad $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(FWDST) # Build BearSSL static library (cross-compiled for freestanding x86_64). BEARSSL_INCLUDES := -isystem $(shell cd .. && pwd)/kernel/freestnd-c-hdrs/x86_64/include -isystem $(abspath include/libc) @@ -215,6 +215,10 @@ klog: libc procmgr: libc $(MAKE) -C src/procmgr +# Build power manager standalone GUI tool (depends on libc). +powermgr: libc + $(MAKE) -C src/powermgr + # Build calculator standalone GUI tool (depends on libc). calculator: libc $(MAKE) -C src/calculator @@ -327,7 +331,7 @@ test_dialogs: libc libloader dialogs $(MAKE) -C src/test_dialogs # Install app bundles (manifests, icons, data files) into bin/apps//. -install-apps: 2048 doom rpgdemo paint spreadsheet wordprocessor weather wikipedia imageviewer fontpreview pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr calculator screenshot texteditor mandelbrot printers timezone crashpad +install-apps: 2048 doom rpgdemo paint spreadsheet wordprocessor weather wikipedia imageviewer fontpreview pdfviewer disks devexplorer installer audio music video bluetooth network terminal klog procmgr powermgr calculator screenshot texteditor mandelbrot printers timezone crashpad ../scripts/install_apps.sh # Copy man pages into bin/man/ so mkramdisk.sh picks them up. @@ -391,6 +395,7 @@ clean: $(MAKE) -C src/terminal clean $(MAKE) -C src/klog clean $(MAKE) -C src/procmgr clean + $(MAKE) -C src/powermgr clean $(MAKE) -C src/calculator clean $(MAKE) -C src/printers clean $(MAKE) -C src/timezone clean diff --git a/programs/src/powermgr/Makefile b/programs/src/powermgr/Makefile new file mode 100644 index 0000000..2bcdf92 --- /dev/null +++ b/programs/src/powermgr/Makefile @@ -0,0 +1,77 @@ +# Makefile for powermgr (standalone Power Manager) on MontaukOS +# Copyright (c) 2026 Daniel Hammer + +MAKEFLAGS += -rR +.SUFFIXES: + +TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-elf- +ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) + CXX := $(TOOLCHAIN_PREFIX)g++ +else + CXX := g++ +endif + +PROG_INC := ../../include +LINK_LD := ../../link.ld +BINDIR := ../../bin +OBJDIR := obj +LIBDIR := ../../lib + +CXXFLAGS := \ + -std=gnu++20 \ + -g -O2 -pipe \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -Wno-unused-function \ + -nostdinc \ + -ffreestanding \ + -fno-stack-protector \ + -fno-stack-check \ + -fno-PIC \ + -fno-rtti \ + -fno-exceptions \ + -ffunction-sections \ + -fdata-sections \ + -m64 \ + -march=x86-64 \ + -msse \ + -msse2 \ + -mno-red-zone \ + -mcmodel=small \ + -MMD -MP \ + -I $(PROG_INC) \ + -isystem $(PROG_INC)/libc \ + -isystem ../../../kernel/freestnd-c-hdrs/x86_64/include \ + -isystem ../../../kernel/freestnd-cxx-hdrs/x86_64/include + +LDFLAGS := \ + -nostdlib \ + -static \ + -Wl,--build-id=none \ + -Wl,--gc-sections \ + -Wl,-m,elf_x86_64 \ + -z max-page-size=0x1000 \ + -T $(LINK_LD) + +SRCS := main.cpp stb_truetype_impl.cpp +OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) + +TARGET := $(BINDIR)/apps/powermgr/powermgr.elf + +.PHONY: all clean + +all: $(TARGET) + +$(TARGET): $(OBJS) $(LINK_LD) Makefile + mkdir -p $(BINDIR)/apps/powermgr + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + +$(OBJDIR)/%.o: %.cpp Makefile + mkdir -p $(OBJDIR) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +-include $(OBJS:.o=.d) + +clean: + rm -rf $(OBJDIR) $(TARGET) diff --git a/programs/src/powermgr/main.cpp b/programs/src/powermgr/main.cpp new file mode 100644 index 0000000..ab2bd20 --- /dev/null +++ b/programs/src/powermgr/main.cpp @@ -0,0 +1,373 @@ +/* + * main.cpp + * MontaukOS Power Manager - GUI equivalent of the `power` command. + * + * Polls the kernel's CPU power/thermal snapshot (SYS_POWERINFO) once per + * second and plots package temperature, average active frequency, and the + * thermal governor's frequency ceiling as scrolling line graphs, plus a + * details panel with the HWP/EPP/idle configuration. + * Copyright (c) 2026 Daniel Hammer + */ + +#include +#include +#include +#include + +extern "C" { +#include +} + +using namespace gui; + +static constexpr int INIT_W = 640; +static constexpr int INIT_H = 520; +static constexpr int PW_TOOLBAR_H = 36; +static constexpr int PW_POLL_MS = 1000; +static constexpr int PW_GRAPH_CAP = 120; + +static constexpr Color PW_TOOLBAR_BG = Color::from_rgb(0xF5, 0xF5, 0xF5); +static constexpr Color PW_HEADER_BG = Color::from_rgb(0xF0, 0xF0, 0xF0); +static constexpr Color PW_BORDER = Color::from_rgb(0xD0, 0xD0, 0xD0); +static constexpr Color PW_DIM_TEXT = Color::from_rgb(0x66, 0x66, 0x66); +static constexpr Color PW_SUCCESS = Color::from_rgb(0x22, 0x88, 0x22); +static constexpr Color PW_WARNING = Color::from_rgb(0xCC, 0x88, 0x00); +static constexpr Color PW_DANGER = Color::from_rgb(0xCC, 0x33, 0x33); +static constexpr Color PW_INFO = Color::from_rgb(0x33, 0x66, 0xCC); +static constexpr Color PW_CEILING = Color::from_rgb(0x00, 0x88, 0x88); + +struct PowerMgrState { + montauk::abi::PowerInfo info; + bool supported; + int mouse_x; + int mouse_y; + uint64_t last_poll_ms; + + uint64_t temp_samples[PW_GRAPH_CAP]; + uint64_t freq_samples[PW_GRAPH_CAP]; + uint64_t ceiling_samples[PW_GRAPH_CAP]; + mtk::GraphHistory temp_history; + mtk::GraphHistory freq_history; + mtk::GraphHistory ceiling_history; +}; + +static WsWindow g_win; +static PowerMgrState g_pw = {}; + +static mtk::Theme pw_theme() { + mtk::Theme theme = mtk::make_theme(); + theme.surface = PW_TOOLBAR_BG; + theme.surface_alt = PW_HEADER_BG; + theme.border = PW_BORDER; + theme.text_muted = PW_DIM_TEXT; + theme.text_subtle = PW_DIM_TEXT; + return theme; +} + +static void init_graph_histories() { + mtk::graph_history_init(&g_pw.temp_history, g_pw.temp_samples, PW_GRAPH_CAP); + mtk::graph_history_init(&g_pw.freq_history, g_pw.freq_samples, PW_GRAPH_CAP); + mtk::graph_history_init(&g_pw.ceiling_history, g_pw.ceiling_samples, PW_GRAPH_CAP); +} + +static bool read_info() { + return montauk::syscall1(montauk::abi::SYS_POWERINFO, (uint64_t)&g_pw.info) == 0; +} + +static bool refresh_state(bool force) { + if (!g_pw.supported) + return false; + + uint64_t now = montauk::get_milliseconds(); + if (!force && now - g_pw.last_poll_ms < PW_POLL_MS) + return false; + + g_pw.last_poll_ms = now; + if (!read_info()) + return false; + + if (g_pw.info.tempC != 0) + mtk::graph_history_push(&g_pw.temp_history, g_pw.info.tempC); + mtk::graph_history_push(&g_pw.freq_history, g_pw.info.effMHz); + mtk::graph_history_push(&g_pw.ceiling_history, g_pw.info.curMaxPerf); + return true; +} + +static Rect toolbar_rect() { + return {0, 0, g_win.width, PW_TOOLBAR_H}; +} + +static Rect refresh_button_rect() { + int btn_h = 26; + int btn_y = (PW_TOOLBAR_H - btn_h) / 2; + return {8, btn_y, 82, btn_h}; +} + +static bool mouse_in_rect(const Rect& rect) { + return rect.contains(g_pw.mouse_x, g_pw.mouse_y); +} + +static void render_toolbar(Canvas& c, const mtk::Theme& theme, int fh) { + Rect bar = toolbar_rect(); + c.fill_rect(bar.x, bar.y, bar.w, bar.h, theme.surface); + c.hline(bar.x, bar.y + bar.h - 1, bar.w, theme.border); + + Rect refresh_rect = refresh_button_rect(); + mtk::draw_button(c, refresh_rect, "Refresh", mtk::BUTTON_TONAL, + mtk::widget_state(false, mouse_in_rect(refresh_rect), + g_pw.supported), theme); + + char status[96]; + if (!g_pw.supported) { + snprintf(status, sizeof(status), "No power management"); + } else if (g_pw.info.throttling) { + snprintf(status, sizeof(status), "%u C, avg %u MHz - THROTTLING", + (unsigned)g_pw.info.tempC, (unsigned)g_pw.info.effMHz); + } else if (g_pw.info.tempC != 0) { + snprintf(status, sizeof(status), "%u C, avg %u MHz", + (unsigned)g_pw.info.tempC, (unsigned)g_pw.info.effMHz); + } else { + snprintf(status, sizeof(status), "avg %u MHz", (unsigned)g_pw.info.effMHz); + } + + int status_w = text_width(status); + Color status_color = (g_pw.supported && g_pw.info.throttling) + ? PW_DANGER : theme.text; + c.text(g_win.width - status_w - 12, (PW_TOOLBAR_H - fh) / 2, status, status_color); +} + +static void render_graph(Canvas& c, + const Rect& rect, + const mtk::GraphHistory& history, + uint64_t max_value, + const char* title, + const char* value, + Color line, + const mtk::Theme& theme) { + mtk::GraphStyle style = mtk::make_graph_style(theme, line); + style.background = theme.window_bg; + style.plot_bg = Color::from_rgb(0xFA, 0xFA, 0xFA); + style.grid = mtk::mix(style.plot_bg, line, 16); + style.fill = mtk::lighten(line, 225); + mtk::draw_line_graph(c, rect, history, max_value, title, value, theme, style); +} + +static constexpr int PW_DETAIL_ROWS = 4; + +static int details_row_h(int fh) { + return fh + 10; +} + +static int details_panel_h(int fh) { + // Mirrors the graph cards: padding, title line, 7px gap, then rows. + return 8 * 2 + fh + 7 + PW_DETAIL_ROWS * details_row_h(fh); +} + +static void render_details(Canvas& c, const Rect& rect, + const mtk::Theme& theme, int fh) { + mtk::draw_rounded_frame(c, rect, theme.radius_md, theme.window_bg, theme.border); + + const montauk::abi::PowerInfo& info = g_pw.info; + int pad = 8; + int x = rect.x + pad; + int y = rect.y + pad; + int w = rect.w - pad * 2; + int row_h = details_row_h(fh); + char buf[96]; + + c.text(x, y, "Details", theme.text_subtle); + y += fh + 7; + + struct Row { + const char* label; + const char* value; + Color color; + } rows[PW_DETAIL_ROWS]; + + char hwp[64]; + if (info.hwpActive) { + snprintf(hwp, sizeof(hwp), "active (EPP 0x%02X, perf range %u-%u)", + (unsigned)info.epp, (unsigned)info.lowestPerf, + (unsigned)info.highestPerf); + } else { + snprintf(hwp, sizeof(hwp), "not active"); + } + rows[0] = {"HWP", hwp, theme.text}; + + snprintf(buf, sizeof(buf), "base %u MHz, turbo %u MHz", + (unsigned)info.baseMHz, (unsigned)info.maxMHz); + rows[1] = {"Frequency", buf, theme.text}; + + char gov[64]; + Color gov_color = theme.text; + if (!info.hwpActive) { + snprintf(gov, sizeof(gov), "inactive"); + } else if (info.throttling) { + snprintf(gov, sizeof(gov), "THROTTLING - ceiling %u of %u", + (unsigned)info.curMaxPerf, (unsigned)info.highestPerf); + gov_color = PW_DANGER; + } else { + snprintf(gov, sizeof(gov), "not throttling (ceiling %u)", + (unsigned)info.curMaxPerf); + gov_color = PW_SUCCESS; + } + rows[2] = {"Governor", gov, gov_color}; + + char idle[48]; + snprintf(idle, sizeof(idle), "MWAIT hint 0x%02X%s", + (unsigned)(info.apIdleHint & 0xFF), + info.apIdleHint == 0 ? " (C1 only)" : ""); + rows[3] = {"AP idle", idle, theme.text}; + + for (int i = 0; i < PW_DETAIL_ROWS; i++) { + c.text(x, y, rows[i].label, theme.text); + int value_w = text_width(rows[i].value); + c.text(x + w - value_w, y, rows[i].value, rows[i].color); + y += row_h; + if (i < PW_DETAIL_ROWS - 1) + mtk::draw_separator(c, x, y - 5, w, theme); + } +} + +static void render_unsupported(Canvas& c, const mtk::Theme& theme, int fh) { + const char* line1 = "No CPU power management available"; + const char* line2 = "(non-Intel CPU or running under emulation)"; + int y = gui_max((g_win.height - fh * 2 - 8) / 2, PW_TOOLBAR_H + 12); + c.text(gui_max((g_win.width - text_width(line1)) / 2, 12), y, + line1, theme.text); + c.text(gui_max((g_win.width - text_width(line2)) / 2, 12), y + fh + 8, + line2, theme.text_muted); +} + +static void render_body(Canvas& c, const mtk::Theme& theme, int fh) { + const montauk::abi::PowerInfo& info = g_pw.info; + + Rect body = {0, PW_TOOLBAR_H, g_win.width, + gui_max(g_win.height - PW_TOOLBAR_H, 0)}; + int margin = 12; + int gap = 10; + int details_h = details_panel_h(fh); + int graph_area_h = gui_max(body.h - margin * 2 - gap * 2 - details_h, 96); + int temp_h = (graph_area_h * 3) / 5; + int row_h = graph_area_h - temp_h - gap; + int col_w = gui_max((body.w - margin * 2 - gap) / 2, 80); + int x0 = body.x + margin; + int y0 = body.y + margin; + int y1 = y0 + temp_h + gap; + int y2 = y1 + row_h + gap; + + Rect temp_rect = {x0, y0, body.w - margin * 2, temp_h}; + Rect freq_rect = {x0, y1, col_w, row_h}; + Rect ceiling_rect = {x0 + col_w + gap, y1, col_w, row_h}; + Rect details_rect = {x0, y2, body.w - margin * 2, details_h}; + + // Scale the plot to TjMax so the top edge is the hardware throttle + // point; the line turns red while the governor is actively limiting. + char temp_value[48]; + if (info.tempC != 0) { + snprintf(temp_value, sizeof(temp_value), "%u C (throttle at %u C)", + (unsigned)info.tempC, (unsigned)info.tjMaxC); + } else { + snprintf(temp_value, sizeof(temp_value), "unavailable"); + } + render_graph(c, temp_rect, g_pw.temp_history, + info.tjMaxC > 0 ? info.tjMaxC : 100, + "Package Temperature", temp_value, + info.throttling ? PW_DANGER : PW_WARNING, theme); + + char freq_value[32]; + snprintf(freq_value, sizeof(freq_value), "%u MHz", (unsigned)info.effMHz); + render_graph(c, freq_rect, g_pw.freq_history, + info.maxMHz > 0 ? info.maxMHz : 1, + "Avg Frequency", freq_value, PW_INFO, theme); + + char ceiling_value[32]; + snprintf(ceiling_value, sizeof(ceiling_value), "%u / %u", + (unsigned)info.curMaxPerf, (unsigned)info.highestPerf); + render_graph(c, ceiling_rect, g_pw.ceiling_history, + info.highestPerf > 0 ? info.highestPerf : 1, + "Frequency Ceiling", ceiling_value, PW_CEILING, theme); + + render_details(c, details_rect, theme, fh); +} + +static void render() { + mtk::StandaloneHost host(&g_win); + Canvas c = host.canvas(); + mtk::Theme theme = pw_theme(); + c.fill(theme.window_bg); + + int fh = system_font_height(); + render_toolbar(c, theme, fh); + + if (g_pw.supported) + render_body(c, theme, fh); + else + render_unsupported(c, theme, fh); +} + +static bool handle_mouse(const montauk::abi::WinEvent& ev) { + bool refresh_hover_before = mouse_in_rect(refresh_button_rect()); + + g_pw.mouse_x = ev.mouse.x; + g_pw.mouse_y = ev.mouse.y; + + bool redraw = refresh_hover_before != mouse_in_rect(refresh_button_rect()); + + bool left_pressed = (ev.mouse.buttons & 1) && !(ev.mouse.prev_buttons & 1); + if (!left_pressed) + return redraw; + + if (refresh_button_rect().contains(ev.mouse.x, ev.mouse.y)) + return refresh_state(true) || redraw; + return redraw; +} + +extern "C" void _start() { + if (!fonts::init()) + montauk::exit(1); + + if (!g_win.create("Power", INIT_W, INIT_H)) + montauk::exit(1); + + montauk::memset(&g_pw, 0, sizeof(g_pw)); + init_graph_histories(); + g_pw.mouse_x = -1; + g_pw.mouse_y = -1; + g_pw.supported = read_info(); + + refresh_state(true); + render(); + g_win.present(); + + while (!g_win.closed) { + bool redraw = refresh_state(false); + + montauk::abi::WinEvent ev; + int r = g_win.poll(&ev); + if (r < 0) break; + + if (r == 0) { + if (redraw) { + render(); + g_win.present(); + } + montauk::sleep_ms(16); + continue; + } + + if (ev.type == 3) + break; + + if (ev.type == 1) redraw |= handle_mouse(ev); + else if (ev.type == 2 || ev.type == 4) redraw = true; + + if (redraw) { + render(); + g_win.present(); + } + } + + g_win.destroy(); + montauk::exit(0); +} diff --git a/programs/src/powermgr/manifest.toml b/programs/src/powermgr/manifest.toml new file mode 100644 index 0000000..93be0be --- /dev/null +++ b/programs/src/powermgr/manifest.toml @@ -0,0 +1,11 @@ +[app] +name = "Power" +binary = "powermgr.elf" +icon = "gnome-power-statistics.svg" + +[menu] +category = "System" +visible = true + +[launch] +pass_home_dir = false diff --git a/programs/src/powermgr/stb_truetype_impl.cpp b/programs/src/powermgr/stb_truetype_impl.cpp new file mode 100644 index 0000000..dd91785 --- /dev/null +++ b/programs/src/powermgr/stb_truetype_impl.cpp @@ -0,0 +1,33 @@ +/* + * stb_truetype_impl.cpp + * Single compilation unit for stb_truetype in MontaukOS freestanding environment + * Copyright (c) 2026 Daniel Hammer + */ + +#include +#include +#include +#include +#include + +#define STBTT_ifloor(x) ((int) stb_floor(x)) +#define STBTT_iceil(x) ((int) stb_ceil(x)) +#define STBTT_sqrt(x) stb_sqrt(x) +#define STBTT_pow(x,y) stb_pow(x,y) +#define STBTT_fmod(x,y) stb_fmod(x,y) +#define STBTT_cos(x) stb_cos(x) +#define STBTT_acos(x) stb_acos(x) +#define STBTT_fabs(x) stb_fabs(x) + +#define STBTT_malloc(x,u) ((void)(u), montauk::malloc(x)) +#define STBTT_free(x,u) ((void)(u), montauk::mfree(x)) + +#define STBTT_memcpy(d,s,n) montauk::memcpy(d,s,n) +#define STBTT_memset(d,v,n) montauk::memset(d,v,n) + +#define STBTT_strlen(x) montauk::slen(x) + +#define STBTT_assert(x) ((void)(x)) + +#define STB_TRUETYPE_IMPLEMENTATION +#include diff --git a/scripts/install_apps.sh b/scripts/install_apps.sh index 36fdc61..a6bf332 100755 --- a/scripts/install_apps.sh +++ b/scripts/install_apps.sh @@ -35,6 +35,7 @@ APPS=( "terminal|apps/scalable/utilities-terminal.svg" "klog|apps/scalable/utilities-terminal.svg" "procmgr|apps/scalable/system-monitor.svg" + "powermgr|apps/scalable/gnome-power-statistics.svg" "calculator|apps/scalable/accessories-calculator.svg" "printers|devices/scalable/preferences-devices-printer.svg" "timezone|categories/scalable/preferences-system-time.svg"